ujimushi(@旧sradjp(15364))の日記

旧スラドの日記の引越先です

LaTeXとJulia言語の幸せな関係

この記事はTeX & LaTeX Advent Calendar 2023の21日目の記事です。 20日目は CareleSmith9さんの簡単に 𝕏 を出力したい。でした。 22日目はKosei Watanabeさんの共通テストの順不同問題のTeXによる自動採点です。

普段,LaTeXはJulia言語等で出力した結果やグラフ画像をとり込んで資料にするのみで,特に取り立てて話す内容はなかったのですが,Julia言語内でLaTeXっぽいところを調べてみようというきっかけがありました。

書こうと思ったきっかけ

Julia言語には,R言語data.framePythonpandasのようなデータフレームを扱うモジュールとして, DataFramesモジュールがあります。 そのドキュメントの中に,「show(io, MIME("text/latex"), df)TeX形式で出力可能」。おおそんなんできるんや。 で試しに次のような簡単なプログラムを書きました。

using DataFrames
using SQLite
db = SQLite.DB("./test.db")
df = DBInterface.execute(db, "SELECT code, filename FROM fileinfo;") |> DataFrame;
show(open("tabular.tex", "w"), MIME("text/latex"), df)

そして出力結果は…

\begin{tabular}{r|cc}
    & code & filename\\
    \hline
    & Int64 & String\\
    \hline
    1 & 1718 & 20230820.dat \\
    2 & 5538 & 20230821.dat \\
    3 & 8553 & 20230822.dat \\
    4 & 4024 & 20230823.dat \\
    5 & 1285 & 20230824.dat \\
    6 & 9747 & 20230825.dat \\
    7 & 1708 & 20230826.dat \\
...
    98 & 3788 & 20231125.dat \\
    99 & 9782 & 20231126.dat \\
    100 & 3743 & 20231127.dat \\
\end{tabular}

おお。これでlongtableのヘッダーに書き換えたら長い表も楽々。 で他にも何かLaTeXと連携して便利な仕組みがないか調べてみた(薄っぺらい)内容がこの記事になります。

unicode文字の入力補助

個人的に一番使っているのはインタラクティブな実行環境上でのunicode文字の補完機能です。

Julia言語はMatlabに大きな影響を受けていることもあり,プログラミング言語の中では 数学的な記述をよくします。また,変数名等で,かなりのunicodeを受けつけることもあり, ラテン文字や下付き文字・記録等を使ってプログラムが書かれていることが多いです。

そのため,Juliaのrepl(インタラクティブな実行環境)ではlatexのmath環境の記述方法でunicodeの記号が入力できます。 \alpha[Tab]ɑ

LaTeXString

LaTeXStringという外部モジュール・型があります。 これは内部に文字列データのみという単純な複合型のデータタイプなのですが,これを用いてグラフのタイトル等をTeX形式で記述することができます。 記述は L"TeXの数式" で可能です。次のグラフはsinc関数の凡例を数式で表した例です。

using Plots
using LaTeXStrings

gr()
plt = plot(sinc, label=L"\frac{\sin\pi x}{\pi x}")
savefig(plt, "latex_plot.png")

Juliaでは一般的にPlotsパッケージでグラフを描画することが多いです。 Plotsパッケージではグラフを描く関数の書式を統一しているものの,描画自体はバックエンドのライブラリ側で行います。そのため,バックエンドによっては対応しない書式もあります。 主なバックエンドを次の図に示します。

バックエンドとの関係

ここで目を引くバックエンドはやはり,PGFPlotsXでしょう。 これは,LaTeXのPGFライブラリのplot機能に対するJulia言語のラッパーライブラリです。個人的には LaTeXでもJulia言語でもない感 が強くてやや敬遠気味ですが,Plotsのバックエンドとして,非常にきれいな図(ubuntu上では,裏でlualatexが走ってpdfでのグラフ表示)を出力します。 もちろん,LaTeXのソースでも出力可能です。バックエンドを変更してからグラフを描画し,savefig(plt, "chart.tex")でOKです。

ここで,先ほどグラフに表示した際,TeXの数式を実際にレンダリングしているモジュールがその名もずばり,Latexifyです。 次はこのパッケージについて説明します。

Latexify

Latexifyパッケージは大きく分けて2つの機能があるようです

  • LaTeXStringを入力して数式をレンダリングして出力する
  • Julia言語の様々なものをLaTeXStringで出力する

大まかなイメージ

latexify

Latexfy.jlのドキュメントのページにもありますが,Julia言語の色々な式について2×3の行列にしたものをlatexify化します。

using Latexify

m = [2//3          "e^(-c*t)"   1+3im
     :(x/(x+k_1))  "gamma(n)"   :(log10(x))]
mylatex = latexify(m)
println(mylatex)

出力結果は次の通りです。

\begin{equation}
\left[
\begin{array}{ccc}
\frac{2}{3} & e^{\left(  - c \right) \cdot t} & 1+3\mathit{i} \\
\frac{x}{x + k_{1}} & \Gamma\left( n \right) & \log_{10}\left( x \right) \\
\end{array}
\right]
\end{equation}

あまりLaTeXの数式に慣れていない学生さんとかちょっと使ってコピペできると便利ですよね。 ですので,latexify関数呼び出しと同時にクリップボードにコピーする機能があります。

Latexify.copy_to_clipboard(true)

とすることで有効になります。

render

lualatexを使ったレンダリングです。上のmylatexm.pngに出力するコード例です。

# starred = false とすると,数式番号がつく
set_default(starred = true)
render(mylatex, MIME("image/png"); name="m")

次の図が出力結果です。

その他Symbolics.jlという数式処理システム(Pythonでいうところのsympyみたいなもの)も使うと色々なことができると思います。 Symbolics.jlでロドリゲスの公式を展開しようの記事のようにかなり高度なことができます。

dataxパッケージ

今回のために色々調べていくうちに見つけたパッケージです。 julia言語などのプログラムの出力結果を手軽にLaTeXで利用するパッケージとして, LaTeX側はdatax,julia言語側はLaTeXDataxというものがあります。

試しに簡単な連立方程式を解く例を試してみましょう。 手順の簡便化のため,同じフォルダにJulia言語,LaTeXのソースファイルを置きます。 eqsの定義のところに,見慣れない~がありますが,=が使えないので,等号の代わりを示す記号です。 solve_forで解いて,結果をresultに入れています。

# datax.jl
using Symbolics: solve_for
using LaTeXDatax
using Symbolics

@variables x y
LaTeXDatax.Latexify.set_default(starred=false)

eqs = [3x + 4y ~ 13, x + 2y ~ 7]
vars = [x, y]
result = solve_for(eqs, vars)
eq_result = vars ~ result

@datax eqs vars result eq_result filename:="data.tex"

上のソースを実行すると,julia側の@datax ... で記述している変数の値をLaTeX側で参照できるようになります。 data.texLaTeX側で利用します。

latex側のソースは次の通りです。\datax{変数名}でJulia側の変数の内容を参照しています。

% datax-example.tex
\documentclass[paper={10cm, 10cm}]{jlreq}
\usepackage{amsmath}
\usepackage[dataxfile=data.tex]{datax}
\pagestyle{empty}
\begin{document}

連立方程式を次式とする。

\datax{eqs}

解は次の通りとなる。

\datax{eq_result}

\end{document}

コンパイルした結果を次に示します。

仕組みはわりと単純ですが,プログラムで演算した結果をそのままLaTeXで参照できるのは便利。 ここでは説明していませんが,julia言語側はUnitfulLaTeX側はsiunitxで単位の扱いも楽にできるようなので,直前まで実験の結果が変わるような論文・資料を書いている学生とかには重宝しそうな気もします。

さいごに

Julia言語は,まだLaTeXの数式に慣れてない学生さんのようなライトなLaTeXユーザーに役立つのではないかと個人的に感じます。 使っているうちにunicodeの記号の入力等で自然とLaTeX記法にふれる機会も増えるでしょう。

私は使えていませんが,DifferentialEquations.jlという微分方程式を解く用途のパッケージも前述のLatexifyと連携していて,数式をよく扱う方には非常に便利ではないかと思います。

ライトなLaTeXユーザーに優しくお財布にも優しい(?)Julia言語。まさしくLaTeXユーザーを幸せにするプログラミング言語の一つと言えるのではないでしょうか?

…とこじつけの結論で締めさせていただきます。