TeX - LaTeX Asked on June 29, 2021
I would like to automate the production of the following output (the formatting is not so good but I will do a better one later).
This picture has been obtained using this code :
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}
I would like to only type the array part of the code.
begin{exvalexpval}
x_k & 0 & 1 & 2 & 3 & 4
hline
p_k & 0.2000 & 0.2 & 0.4 & 0.05 & 0.15
end{exvalexpval}
The algorithm could be the following one but I do not know how to do that with expl3
.
r|c|c|c|c|c
of NiceArray
.red
, blue
, black!60!green
, orange
and gray
will be really needed. If more colors are needed, just use a cycle of colors.Note : I do not want to calculate the value of the expected value. There will be cases of use with formal values in the table.
Here is a possible solution.
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
newcommanddecoframe[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}
}
newcommanddecobox[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}}
xsb{k} & l__tnscalc_xline_temp_tl
hline
psb{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) = sumlimitssb{k=1}^{int_use:N l__tnscalc_numcol_int} psb{k} cdot xsb{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
setlengthparindent{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}
Correct answer by projetmbc on June 29, 2021
This is my first go at the code. I am trying to learn LaTeX3, so I shamelessly admit this is a bit a bait so that someone will bleah over it and will try to teach me the correct way...
In this first code (this is just my second snippet in expl3
), there are no color boxes, etc --- it's just a proof of concept. I have to think a bit more about how to do it. There is also no check whatsoever --- put lists with different lengths here and anything can happen.
documentclass[fleqn]{article}
usepackage{amsmath}
usepackage{expl3}
usepackage{xparse}
ExplSyntaxOn
seq_new:N l_mbc_listx_seq
seq_new:N l_mbc_listp_seq
NewDocumentCommandShowExpectedCalculation{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}}
#1sb{#3} & seq_use:Nn l_mbc_listx_seq { & }
#2sb{#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) = sumsb{#3=1}sp{int_use:N l_mbc_N_int} #1sb{#3}#2sb{#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}
There is probably a better way to map together a couple (or three, that I need in case of color) sequences, but I have not yet read it ;-)...
Answered by Rmano on June 29, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP