根据https://towardsdatascience.com/5-ways-julia-is-better-than-python-334cc66d64ae(第 2 项)内容如下
Julia code is universally executable in R, Latex, Python, and C.
我在 Google 上搜索了一下,找不到如何做到这一点的例子。当然,你需要有朱莉娅除了 TexLive 之外,它还安装在个人电脑上。
当然,我不是在谈论在 Latex 中列出 Julia 代码。也不是在谈论在 Julia 中使用 Latex。
上面的内容Julia code executable in Latex
对我来说意味着可以编写一些 Julia 函数并从 Latex 中调用它并返回结果。与现在从 Lualatex 使用 Lua 相同。从 Latex 调用 Python 时也一样。
至少我是这么理解上述内容的。
如果可以的话,我们能否提供一个很小的例子来说明如何做到这一点?
首先,这是我之前写的关于在 Latex 中使用 Python 的 MWE
\documentclass[11pt]{article}%
\usepackage{pythontex}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\begin{document}
\begin{pyconsole}
x = 987.27
x = x**2
\end{pyconsole}
The variable is $x=\pycon{x}$
\end{document}
需要像这样编译:
pdflatex foo.tex
/usr/local/texlive/2019/bin/x86_64-linux/pythontex foo.tex
pdflatex foo.tex
如何为 Julia 做类似上述的事情?
答案1
Julia 有一个 C-API,您可以通过 FFI 在 LuaTeX 中使用它。它需要一些样板代码,您可以在其中重复一些函数原型API以及一些用于在 C 类型和 Lua 类型之间进行转换的包装器。这实际上非常轻松。将此文件保存julia.lua
在与文档相同的目录中。
julia.lua
local ffi = require("ffi")
local JULIA = ffi.load("julia", true)
ffi.cdef [[
// Types
typedef struct _jl_value_t jl_value_t;
// Initialization
void jl_init__threading(void);
void jl_init_with_image__threading(const char *julia_bindir,
const char *image_relative_path);
// Execution and conversion
jl_value_t *jl_eval_string(const char*);
const char *jl_string_ptr(jl_value_t *);
const char *jl_typeof_str(jl_value_t *);
]]
local julia_initialized = false
local julia = {}
function julia.init(rpath)
-- Initialize the Julia interpreter (singleton)
if not julia_initialized then
if rpath then
JULIA.jl_init_with_image__threading(rpath, "sys.so")
else
JULIA.jl_init__threading()
end
julia_initialized = true
end
end
function julia.run(expr)
assert(julia_initialized)
JULIA.jl_eval_string(expr)
end
function julia.eval(expr)
assert(julia_initialized)
local jlval, cstr, str
jlval = JULIA.jl_eval_string(expr)
-- First check that the datatype
if jlval ~= ffi.NULL then
cstr = JULIA.jl_typeof_str(jlval)
else
return nil
end
if cstr ~= ffi.NULL then
str = ffi.string(cstr)
else
return nil
end
-- if the datatype is string, convert to Lua string
if str == "String" then
cstr = JULIA.jl_string_ptr(jlval)
else
return nil
end
if cstr ~= ffi.NULL then
str = ffi.string(cstr)
else
return nil
end
return str
end
return julia
您现在可以通过 在您的文档中使用此模块require("julia")
。它提供三种功能:
julia.init(rpath)
必须在调用其他函数之前调用此函数一次以初始化解释器。根据您的安装,可能需要提供 Julia 的运行时路径作为参数rpath
(另请参阅从 Lua 调用 Julia)。在我的安装中,这不是必需的,我可以直接省略该参数。julia.run(expr)
只是跑expr
。julia.eval(expr)
这也运行表达式expr
但尝试将最后一个值转换为expr
字符串并返回它。
您传递给此代码的 Julia 代码应该没有错误,因为没有在 Julia 级别检查错误。我不知道解释器是否会在发现错误时放弃,但这也会使您的文档编译崩溃。
在这里,我将julia.eval
函数包装到一些特定于 TeX 的参数扫描和打印中,并将其分配给一个名为的宏,\directjulia
该宏的使用方式类似于\directlua
。与类似的东西相比,它最大的好处pythontex
是一切都是完全可扩展的。您必须使用 来处理文档--shell-escape
。
\documentclass{article}
\usepackage{luacode}
\begin{luacode*}
julia = require("julia")
julia.init()
local t = lua.get_functions_table()
t[#t + 1] = function()
local expr = token.scan_string()
local str = julia.eval(expr)
if str then
tex.sprint(str)
end
end
token.set_lua("directjulia", #t, "global")
\end{luacode*}
\begin{document}
\begin{luacode*}
julia.run[===[
x = [1 2 3]'
A = [1 0 1; 0 1 1; 1 1 0]
y = x'*A*x
]===]
\end{luacode*}
\edef\value{\directjulia{string(y[1])}}
\texttt{\meaning\value}
\end{document}
答案2
PythonTeX 几乎开箱即用地支持 Julia。你只需要明确说明你想使用 Julia,以避免命名冲突。这里是 MWE。
\documentclass{article}
\usepackage[usefamily={julia,jl}]{pythontex}
\begin{document}
\begin{jlcode} % Or {juliacode}
α = 23.15;
α² = α^2;
\end{jlcode}
% To print it to LaTeX, `print()` directly from Julia or use `\jl` or `\julia`:
$ \alpha^2 = \jl{α²} $!
\end{document}
并使用(或任何引擎)进行编译:
xelatex document.tex
pythontex document.tex
xelatex document.tex
我认为没有必要说你需要安装 Julia 并从你的系统访问它。不幸的是,由于这个原因,它无法在 Overleaf 上运行。
读文档查看更多详细信息。