LuaTeXで分散の計算の途中の表を自動生成する(データと平均値が整数のみのケース)
データの分析で分散を手計算させることがある。
私が問題を作成するときも、分散計算は単純な値で計算させる。今時、コンピュータで計算させるのが普通であるからである。手で計算するのは、理解を深めるためである。その目的であれば、複雑な数値の計算は一切やらせなくて良い。
複雑な計算でない以上、解答を作成をするときに計算でミスをすることは考えにくい。しかし、途中式に書くあれこれが間違いやすい。
一番ありえるミスが、問題文のデータと途中式のデータが一致しないことである。試験問題を演習プリントに貼り付けて(あるいは逆)、試験問題と演習プリントをいったりきたりするうちに、何箇所かデータがずれる、というのがよくある話である。そこで、データの配列を与えたら途中式の表を作るスクリプトを書いてみた。
以下のようなものを作ることを考える。
Luaの部分。
function data_to_problem(data) --問題文に表示するデータの整形 for i=1, #data -1 do tex.print(data[i] .. ",") end tex.print(data[#data]) end function data_to_mean(data) --平均値を計算する関数 sum = 0 for i=1, #data do sum = sum + data[i] end return sum/#data end function repeat_str(rep_str,n) --文字列を繰り返す str ="" for i=1, n do str = str .. rep_str end return str end function add_ary_str(ary, str_pre, str_m, str_end,math_chr) --配列の前後に色々とくっつけるための関数 str = str_pre for i=1, #ary -1 do str = str ..math_chr .. ary[i] .. math_chr .. str_m end str = str .. math_chr .. ary[#ary] .. math_chr .. str_end return(str) end function data_to_vartable(data) str ="" -- 表の1行目・2行目の部分 str = str .. "\\begin{tabular}{|c|" .. repeat_str("c",#data) .. "|c|}" .. " \\hline \n" --\nの前にhlineでないとエラー str = str .. add_ary_str(data,"x &","& ","&合計","$") .. "\\\\" .. "\\hline " .."\n" --データを並べた列 -- 表の3・4行目に必要となる値と配列を計算 x_minus_m ={} x_minus_m_square = {} sum_square = 0 for i =1, #data do x_minus_m[i] = data[i] - data_to_mean(data) x_minus_m_square[i] = (x_minus_m[i])^2 sum_square = sum_square + x_minus_m_square[i] end -- 表の3行目・(x-\bar{x}) str = str .. add_ary_str(x_minus_m, "$x-\\bar{x}$ &", "&", "&","$") .. "\\\\ \\hline \n" -- 表の4行目・(x-\bar{x})^2 str = str .. add_ary_str(x_minus_m_square, "$(x-\\bar{x})^2$ &", "&","&" .. sum_square,"$") .. "\\\\ \\hline " --hlineの後で改行を入れると一行追加になってしまうので入れない。 str = str .. "\\end{tabular}" tex.print(str) end
TeXの部分
\documentclass{ltjsarticle} \usepackage{luacode} \usepackage{amsmath} \usepackage{tcolorbox} \begin{luacode*} --ここに上のluaのコードが入る \end{luacode*} \begin{document} \def\xa{{1,2,3,4,5,6,7}} 次のデータについて、分散および標準偏差の値を求めよ。 \[ \luaexec{data_to_problem(\xa)} \] \begin{tcolorbox}[colframe=white,colback=white,visible] % \begin{center} \luaexec{data_to_vartable(\xa)} \end{center} \end{tcolorbox}
問題部分はdata_to_problemで作っている。文字列を少し加工しているだけである。
表の部分でいろいろとややこしいことをしている。文字列の加工に関しては
- ccccの部分を作るためのrepeat_str
- & $ary[1]$ &ary[2] ... を作るためのadd_ary_str
の2つの関数を使って作っている。
表は最初と最後に例外が色々ある。それに対応させるため、2.のadd_ary_str色々と面倒なことをしている。そして、2.のadd_ary_strに、あらかじめ必要な計算をした配列とオプションを与えて、表の各行の文字列を生成している。
&$ary[1]$の部分は、関数を引数にとらせる関数を作れ美しくできそうなのはなんとなくわかっている。ただ、現在はまだうまくいっていない。よって、強引に処理している(今後の課題)。
その他の課題は、分数への対応である。今回、計算結果を自動表示するものを書かなかったのも、この対応ができなかったからである。色々な問題の自動生成をする以上、有理数を統一的にうまく扱う仕組みは早く考えてしまわないとまずいのはわかっているが・・・