这是代码。
\documentclass{article}
\begin{document}
\directlua{tex.sprint(tostring(math.sin(math.pi)))} \\
\directlua{tex.sprint(tostring(math.tan(math.pi/2)))}
\end{document}
我期望答案为0
和error
。上面的代码给出了一些非常小和非常大的数字。我可以通过修改代码来获得预期的答案吗?
答案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。我必须解决三个不同的错误。
symmath
积极尝试使用 FFI 来加速复数运算。FFI 在 LuaTeX 中始终可用,但仅在启用 shell 转义时才可用,因此当未启用 shell 转义时,我会删除 FFI。安装的 Lua 包加载器
lualibs
存在某种错误,不允许在 中出现两个问号package.path
。我不确定是什么原因造成的,所以我在这里报告了它:https://github.com/latex3/lualibs/issues/2相反,我只是
package.searchpath
手动使用和传递修改后的路径而不进行修改package.path
。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}