2

Here is the code.

\documentclass{article}
\begin{document}
\directlua{tex.sprint(tostring(math.sin(math.pi)))} \\
\directlua{tex.sprint(tostring(math.tan(math.pi/2)))}
\end{document}

I am expecting the answers as 0 and error . The code above gives some very small and big number. Can I get the expected answers by some modifications in code?

4
  • Why are you expecting 0 and inf? Because these are the analytical values? That is not how a computer evaluates these functions. Apr 16, 2020 at 7:41
  • 1
    Your code also shows the number one gotcha of LuaTeX, namely calling tex.sprint with a number. Always use tex.sprint(tostring(<number>)) unless you know what you are doing. Apr 16, 2020 at 7:54
  • @HenriMenke Is there a library to perform these types of calculations in LaTeX? If not, has Lua and LuaTeX enough Capabilities in which such library can be developed for LaTeX? I am referring to this christopheremoore.net/symbolic-lua
    – user61681
    Apr 16, 2020 at 8:12
  • In principle yes, you can use the library you linked but there is a bug in lualibs that prevents that currently: github.com/latex3/lualibs/issues/2 Apr 17, 2020 at 0:14

1 Answer 1

4

In the comments you have proposed using a library for symbolic calculations, which I think is a good solution to this problem.

To this end, you have to download the library you linked and its dependencies. Because they are hosted on GitHub I download them using Git.

git clone https://github.com/thenumbernine/symmath-lua symmath
git clone https://github.com/thenumbernine/lua-ext ext

Then my document directory looks something like this:

.
├── ext
│   [...]
│   ├── ext.lua
│   [...]
├── symmath
│   [...]
│   ├── symmath.lua
│   [...]
└── test.tex

Then the MWE below can be used. There I have to work around three distinct bugs.

  1. symmath aggressively tries to use FFI to speed up complex number operations. FFI is always available in LuaTeX but only usable when shell escape is enabled, so I remove FFI when shell escape is not enabled.

  2. The Lua package loader that is installed by lualibs has some kind of bug which does not allow two questions marks in the package.path. I'm not sure what is causing this, so I've reported it here: https://github.com/latex3/lualibs/issues/2

    Instead I just use package.searchpath and pass the modified path by hand without modifying package.path.

  3. symmath expects Constant to be in the global scope which is not the default.

\documentclass{article}
\usepackage{luacode}
\begin{luacode*}
-- Disable FFI without shell escape
if status.shell_escape ~= 1 then
    package.loaded.ffi = nil
end

-- Work around loader bug
local file, err = package.searchpath("symmath", package.path .. ";./?/?.lua")
if not err then
    package.preload["symmath"] = loadfile(file)
end

-- Load symmath
sym = require("symmath")
Constant = sym.Constant -- bug in symmath
\end{luacode*}
\begin{document}
\[ \sin\pi = \directlua{tex.sprint(tostring(sym.eval(sym.sin(sym.pi))))} \]
\[ \tan\pi/2 = \directlua{tex.sprint(tostring(sym.eval(sym.tan(sym.pi / 2))))} \]
\end{document}

enter image description here


Update 2022-04-12

Since this answer was written a lot has happened and the loader bug was fixed. Also symmath has seen ongoing development and is actively maintained, so it seems it is a very good choice for symbolic math in Lua.

The directory structure for the document remains the same as shown above. But instead of the awkward manual loading, it is now possible to use the luapackageloader package in conjunction with appending to package.path.

To not pollute the global environment with symbols, symmath offers a setup function which takes an environment table to insert its functions into.

The only drawback is that the ffi still has to be disabled manually when not using --shell-escape. I think a bug report to the developers is in order once I find a simple reproducer.

\documentclass{article}
\usepackage{luacode}
\usepackage{luapackageloader}
\begin{luacode*}
-- Disable FFI without shell escape
if status.shell_escape ~= 1 then
    package.loaded.ffi = nil
end

-- Load symmath
package.path = package.path .. ";./?/?.lua"
sym = {}
require("symmath").setup{env=sym}
\end{luacode*}
\begin{document}
\[ \sin\pi = \directlua{tex.sprint(tostring(sym.eval(sym.sin(sym.pi))))} \]
\[ \tan\pi/2 = \directlua{tex.sprint(tostring(sym.eval(sym.tan(sym.pi / 2))))} \]
\end{document}
9
  • This is nice wayout. I am curious to know your views about symath. Is symmath well built and structured to serve as mini computer algebra system for luaLaTeX or is there scope to start new project which can serve as mini computer algebra system for luaLaTeX?
    – user61681
    Apr 17, 2020 at 13:13
  • @user61681 I haven't looked at symmath in too much detail but it seems to be very versatile. You could have a look at the tests to see what can be done. You should not use the setup function with LuaTeX, though, because that pulls all kinds of things into the global namespace that will clash with LuaLaTeX internals. Apr 17, 2020 at 23:10
  • 1
    Hello, symmath author here. Thanks for using symmath. I saw your point #3 and cleaned up a few of the dangling require 'symmath.Constant' references in the code. Hopefully the bugs are fixed. Feel free to report them. Also, you can use require 'symmath'.setup{env=env} in combination with setfenv/_ENV to unload the API into a local scope and not pollute the global namespace. In fact, I added examples of this to most the tests (in my effort to cleanup the dangling require 'symmath.Constant' references). Apr 24, 2020 at 13:40
  • 1
    @user61681 Answers on this site reflect the state of the art when they were written. Nobody has time to run around and update all their old answers. Maybe I can have a look later this week. Apr 11, 2022 at 19:23
  • 1
    @user61681 Thank you for the kind words. I have added an update to the my answer. Apr 12, 2022 at 17:49

You must log in to answer this question.

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