我想自动生成以下输出(格式不太好,但稍后我会做得更好)。
该图片是使用此代码获得的:
\documentclass[12pt,a4paper]{article}
\usepackage{nicematrix}
\usepackage{tikz}
\usetikzlibrary{fit}
\usepackage{tcolorbox}
\tcbuselibrary{theorems}
\begin{document}
$\begin{NiceArray}{r|c|c|c|c|c}[name=tab]
x_k & 0 & 1 & 2 & 3 & 4 \\
\hline
p_k & 0.2000 & 0.2 & 0.4 & 0.05 & 0.15 \\
\end{NiceArray}$
\begin{tikzpicture}[remember picture,overlay]
\node[draw = red,
rounded corners,
fit = (tab-1-2.north west) (tab-1-2.north east)
(tab-2-2.south west) (tab-2-2.south east)] {};
\node[draw = blue,
rounded corners,
fit = (tab-1-4.north west) (tab-1-4.north east)
(tab-2-4.south west) (tab-2-4.south east)] {};
\node[draw = black!60!green,
rounded corners,
fit = (tab-1-6.north west) (tab-1-6.north east)
(tab-2-6.south west) (tab-2-6.south east)] {};
\end{tikzpicture}
$E(X) = \sum_k p_k x_k$
$E(X) = \tcboxmath[colframe = red]%
{0.2000 \cdot 0}
+ 0.2 \cdot 1
+ \tcboxmath[colframe = blue]%
{0.4 \cdot 2}
+ 0.05 \cdot 3
+ \tcboxmath[colframe = black!60!green]%
{0.15 \cdot 4}$
\end{document}
我只想输入代码的数组部分。
\begin{exvalexpval}
x_k & 0 & 1 & 2 & 3 & 4 \\
\hline
p_k & 0.2000 & 0.2 & 0.4 & 0.05 & 0.15 \\
\end{exvalexpval}
该算法可能是以下算法,但我不知道如何使用expl3
。
- 将 xk 值存储在列表中。
- 将 pk 值存储在其他列表中。
- 使用列表的长度来构建
r|c|c|c|c|c
的参数NiceArray
。 - 使用两个列表来构建表格后的内容。
- 什么颜色?实际上我认为真正需要的颜色不超过 、 、 和 五种
red
。blue
如果black!60!green
需要更多颜色,只需使用颜色循环即可orange
。gray
笔记 :我不想计算期望值的值。会有使用表格中正式值的情形。
答案1
这是我第一次尝试编写代码。我正在尝试学习 LaTeX3,所以我毫不羞愧地承认这有点像诱饵,这样有人就会噫并会尝试教我正确的方法......
在第一个代码中(这只是我的第二个代码片段expl3
),没有颜色框等 --- 这只是概念证明。我必须再多想想如何去做。也没有任何检查 --- 在这里放入不同长度的列表,任何事情都可能发生。
\documentclass[fleqn]{article}
\usepackage{amsmath}
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_mbc_listx_seq
\seq_new:N \l_mbc_listp_seq
\NewDocumentCommand\ShowExpectedCalculation{mmmmm} % x, p, index, list x, list p
{
\seq_set_split:Nnn \l_mbc_listx_seq {,} {#4}
\seq_set_split:Nnn \l_mbc_listp_seq {,} {#5}
\int_zero_new:N \l_mbc_N_int
\int_set:Nn \l_mbc_N_int { \seq_count:N \l_mbc_listx_seq }
%
% generate the first table
%
\[
\begin{array}{l|*{\int_use:N \l_mbc_N_int}{c}}
#1\sb{#3} & \seq_use:Nn \l_mbc_listx_seq { & } \\
#2\sb{#3} & \seq_use:Nn \l_mbc_listp_seq { & } \\
\end{array}
\]
%
% generate the generic formula. Use \sb here, `_` in ExplSyntaxOn is a normal letter
%
\[
E(x) = \sum\sb{#3=1}\sp{\int_use:N \l_mbc_N_int} #1\sb{#3}#2\sb{#3}
\]
%
% generate the expansion of the sum in a new sequence list
%
\int_zero_new:N \l_cnt_int
\int_incr:N \l_cnt_int
\fp_zero_new:N \l_expected_fb
\seq_clear_new:N \l_tmp_seq
\int_do_while:nn {\l_cnt_int <= \int_use:N \l_mbc_N_int}
{
\seq_put_right:Nx \l_tmp_seq {
{\seq_item:Nn \l_mbc_listx_seq {\int_use:N \l_cnt_int}}
\cdot
{\seq_item:Nn \l_mbc_listp_seq {\int_use:N \l_cnt_int}}
}
\fp_add:Nn \l_expected_fb {
\seq_item:Nn \l_mbc_listx_seq {\int_use:N \l_cnt_int}
*
\seq_item:Nn \l_mbc_listp_seq {\int_use:N \l_cnt_int}
}
\int_incr:N \l_cnt_int
}
\[
E(x) = \seq_use:Nn \l_tmp_seq {+} = \fp_use:N \l_expected_fb
\]
}
\ExplSyntaxOff
\begin{document}
\ShowExpectedCalculation{x}{p}{k}{0, 1, 2, 3, 4}{0.2, 0.2, 0.4, 0.05, 0.15}
\ShowExpectedCalculation{L}{p}{i}{-1, 0, 1}{0.2, 0.4, 0.4}
\ShowExpectedCalculation{Y}{p}{j+z}{3}{1}
\end{document}
可能有更好的方法将几个(或三个,如果需要颜色的话我需要)序列映射在一起,但我还没有读过;-)...
答案2
这是一个可能的解决方案。
\documentclass{article}
\usepackage{nicematrix}
\usepackage{tikz}
\usetikzlibrary{fit}
\usepackage{tcolorbox}
\tcbuselibrary{theorems}
% Sources
% * https://tex.stackexchange.com/a/475291/6880
% * https://tex.stackexchange.com/a/558343/6880
% * https://tex.stackexchange.com/a/558185/6880
\newcommand\decoframe[3]{
\begin{tikzpicture}[remember picture, overlay]
\node[draw = #1,
rounded corners,
thick,
fit = (#2.north west) (#2.north east)
(#3.south west) (#3.south east)] {};
\end{tikzpicture}
}
\newcommand\decobox[2]{
\tcboxmath[colframe = #1,
left = 0mm, right = 0mm, top = 0mm, bottom = 0mm,
boxsep = 1mm, ,boxrule = 1pt]{#2}
}
\ExplSyntaxOn
% Global variables used.
\seq_new:N \l__tnscalc_colors_seq
\tl_new:N \l__tnscalc_actual_color_temp_tl
\seq_new:N \l__tnscalc_calcexpval_seq
\seq_new:N \l__tnscalc_subseq_seq
\tl_new:N \l__tnscalc_xline_temp_tl
\tl_new:N \l__tnscalc_pline_temp_tl
\int_new:N \l__tnscalc_nbline_int
\int_new:N \l__tnscalc_numcol_int
\int_new:N \l__tnscalc_numcol_deco_int
\int_new:N \l__tnscalc_numcol_decotwo_int
% #1 : line separator
% #2 : cell separator
% #3 : content
\NewDocumentCommand{\calcexpval}{O{red,blue,orange,gray} m m +m} {
\tnscalc_calcexpval:nnnn{#1}{#2}{#3}{#4}
}
% The internal version of the general purpose macro
\cs_new_protected:Nn \tnscalc_calcexpval:nnnn {
% #1 (option) : colors
% #2 : line separator
% #3 : cell separator
% #4 : content
% Colors.
\seq_set_split:Nnn \l__tnscalc_colors_seq { , } { #1 }
% Split into lines
\seq_set_split:Nnn \l__tnscalc_calcexpval_seq { #2 } { #4 }
\int_set:Nn \l__tnscalc_nbline_int { \seq_count:N \l__tnscalc_calcexpval_seq }
% Split each line into cells.
\seq_pop_left:NN \l__tnscalc_calcexpval_seq \l__tnscalc_xline_temp_tl
\seq_set_split:NnV \l__tnscalc_x_seq { #3 } \l__tnscalc_xline_temp_tl
\seq_pop_left:NN \l__tnscalc_calcexpval_seq \l__tnscalc_pline_temp_tl
\seq_set_split:NnV \l__tnscalc_p_seq { #3 } \l__tnscalc_pline_temp_tl
% Number of columns (offensive programming)
\int_set:Nn \l__tnscalc_numcol_int { \seq_count:N \l__tnscalc_x_seq }
\int_set:Nn \l__tnscalc_numcol_deco_int { 2 }
% The table of values
\[%|*{\int_use:N \l_mbc_N_int}{c}
\begin{NiceArray}{r*{\int_use:N \l__tnscalc_numcol_int}{|c}}
x\sb{k} & \l__tnscalc_xline_temp_tl \\
\hline
p\sb{k} & \l__tnscalc_pline_temp_tl
\CodeAfter
\int_add:Nn \l__tnscalc_numcol_int {2}
\bool_while_do:nn { \int_compare_p:nNn \l__tnscalc_numcol_deco_int < \l__tnscalc_numcol_int }{
\seq_pop_left:NN \l__tnscalc_colors_seq \l__tnscalc_actual_color_temp_tl
\seq_put_right:NV \l__tnscalc_colors_seq {\l__tnscalc_actual_color_temp_tl}
\decoframe{\l__tnscalc_actual_color_temp_tl}{1-\int_use:N \l__tnscalc_numcol_deco_int}{2-\int_use:N \l__tnscalc_numcol_deco_int}
\int_add:Nn \l__tnscalc_numcol_deco_int {2}
}
\end{NiceArray}
\]
% Explain the calculus of the expected value.
\int_set:Nn \l__tnscalc_numcol_deco_int { 1 }
$E(X) = \sum\limits\sb{k=1}^{\int_use:N \l__tnscalc_numcol_int} p\sb{k} \cdot x\sb{k}$
\par
$E(X) =
\bool_while_do:nn { \int_compare_p:nNn \l__tnscalc_numcol_int > 0 }{
\seq_pop_left:NN \l__tnscalc_x_seq \l__tnscalc_xval_tl
\seq_pop_left:NN \l__tnscalc_p_seq \l__tnscalc_pval_tl
\bool_if:NTF { \int_compare_p:nNn { \int_eval:n{ \int_mod:nn \l__tnscalc_numcol_deco_int 2} } = 1 } {
\seq_pop_left:NN \l__tnscalc_colors_seq \l__tnscalc_actual_color_temp_tl
\seq_put_right:NV \l__tnscalc_colors_seq {\l__tnscalc_actual_color_temp_tl}
\decobox{\l__tnscalc_actual_color_temp_tl}{\l__tnscalc_xval_tl \cdot \l__tnscalc_pval_tl}
} {
\l__tnscalc_xval_tl \cdot \l__tnscalc_pval_tl
}
\bool_if:NTF { \int_compare_p:nNn \l__tnscalc_numcol_int = 1 } { } { + }
\int_add:Nn \l__tnscalc_numcol_deco_int {1}
\int_add:Nn \l__tnscalc_numcol_int {-1}
}
$
}
\ExplSyntaxOff
\setlength\parindent{0pt}
\begin{document}
Let's try...
\calcexpval{\\}{&}{
0 & 1 & 2 & 3 & 4 \\
0.2000 & 0.2 & 0.4 & 0.05 & 0.15
}
With the default cycle of colors.
\calcexpval{\\}{&}{
0 & 1 \\
0.2000 & 0.2
}
With an odd number of columns and the cycle of colors \verb#blue,gray#.
\calcexpval[blue,gray]{\\}{&}{
0 & 1 & 2 \\
0.2000 & 0.2 & 0.4
}
With a single( ? ) column and the cycle of colors \verb#black#..
\calcexpval[black]{\\}{&}{
0 \\
0.2000
}
%With the short cycle of colors \verb#blue,red#..
\calcexpval[blue,red]{\\}{&}{
0 & 1 & 2 & 3 & 4 & 1 & 2 & 3 \\
0.2000 & 0.2 & 0.4 & 0.05 & 0.15 & 0.2 & 0.4 & 0.05
}
\end{document}