更新 2022-04-12

更新 2022-04-12

这是代码。

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

我期望答案为0error。上面的代码给出了一些非常小和非常大的数字。我可以通过修改代码来获得预期的答案吗?

答案1

在评论中,您提出使用符号计算库,我认为这是解决此问题的好方法。

为此,您必须下载链接的库及其依赖项。因为它们托管在 GitHub 上,所以我使用 Git 下载它们。

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

然后我的文档目录看起来像这样:

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

然后可以使用下面的 MWE。我必须解决三个不同的错误。

  1. symmath积极尝试使用 FFI 来加速复数运算。FFI 在 LuaTeX 中始终可用,但仅在启用 shell 转义时才可用,因此当未启用 shell 转义时,我会删除 FFI。

  2. 安装的 Lua 包加载器lualibs存在某种错误,不允许在 中出现两个问号package.path。我不确定是什么原因造成的,所以我在这里报告了它:https://github.com/latex3/lualibs/issues/2

    相反,我只是package.searchpath手动使用和传递修改后的路径而不进行修改package.path

  3. symmath期望Constant处于全局范围内,但这不是默认的。

\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}

在此处输入图片描述


更新 2022-04-12

自从写下这个答案以来,发生了很多事情,加载器错误也得到了修复。此外,symmath 也一直在不断发展,并得到积极维护,因此它似乎是 Lua 中符号数学的一个非常好的选择。

文档的目录结构与上面显示的相同。但现在可以将luapackageloader包与附加到一起使用,而不必进行笨拙的手动加载package.path

为了不让符号污染全局环境,symmath 提供了一个setup函数,它使用环境表来插入其函数。

唯一的缺点是ffi不使用时必须手动禁用--shell-escape。我认为一旦我找到一个简单的重现程序,就应该向开发人员提交错误报告。

\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}

相关内容