2

How to store a calculated value in array?

zz(1) = ( xx(1) + yy(1) )/2

\fpeval\zz(\counter){(\xx(\counter)+\yy(\counter))/2} NOT working

\documentclass{beamer}
\usepackage{siunitx,amsmath}
\usepackage{xparse,xfp}

\ExplSyntaxOn
\NewDocumentCommand{\newarray}{m}
 {
  \seq_new:c { l_hafid_array_#1_seq }
  \cs_new:cpn { #1 } ##1
   {
    \seq_item:cn { l_hafid_array_#1_seq } { ##1 }
   }
 }
\NewDocumentCommand{\readarray}{mm}
 {
  \seq_set_split:cnn { l_hafid_array_#1_seq } { & } { #2 }
 }
\cs_generate_variant:Nn \seq_set_split:Nnn { c }

\NewExpandableDocumentCommand{\sumarray}{O{15}m}
 {
  \fp_eval:n { round( \seq_use:cn { l_hafid_array_#2_seq } { + }, #1 ) }
 }

\ExplSyntaxOff

\begin{document}

\newarray{xx}
\readarray{xx}{1&2&3&4&5}

\newarray{yy}
\readarray{yy}{6&7&8&9&10}

\begin{frame}
\begin{table}[]
\begin{tabular}{cccc}
No & xx & yy & zz   \\ \hline
1 & \xx{1} & \yy{1} &  \fpeval{(\xx{1}+\yy{1})/2}  \\
2 & \xx{2} & \yy{2} &  \fpeval{(\xx{2}+\yy{2})/2}  \\
3 & \xx{3} & \yy{3} &    \\
4 & \xx{4} & \yy{4} &    \\
5 & \xx{5} & \yy{5} &    \\ \hline
\end{tabular}
\end{table}
\end{frame}

%\newarray{zz}
%\readarray{xx}{0&0&0&0&0}
\newcount\counter
\counter=5
\loop
\fpeval\zz(\counter){(\xx(\counter)+\yy(\counter))/2}
\advance \counter by -1
\unless\ifnum \counter<1
\repeat

\end{document}
sandu
  • 7,950

3 Answers3

3

You cannot assign values to arrays that way: the values in them can be retrieved by a numeric address, but not so assigned.

You can have arrays that are addressable by index both for retrieving and assigning values, using the fparray module.

Arrays have fixed length; with \newarray{<name>} the assigned length is 100; if you need smaller or larger arrays, you can call \newarray{<name>}[<length>].

\documentclass{article}
\usepackage{xparse,xfp}

\ExplSyntaxOn

\NewDocumentCommand{\newarray}{mO{100}}
 {
  \fparray_new:cn { g_sandu_#1_fparray } { #2 }
  \cs_new:cpn { #1 } ##1
   {
    \fparray_item:cn { g_sandu_#1_fparray } { ##1 }
   }
 }

\NewDocumentCommand{\readarray}{mm}
 {
  \seq_set_split:Nnn \l__sandu_temp_seq { & } { #2 }
  \int_step_inline:nn { \seq_count:N \l__sandu_temp_seq }
   {
    \fparray_gset:cne { g_sandu_#1_fparray } { ##1 }
     { \seq_item:Nn \l__sandu_temp_seq { ##1 } }
   }
 }

\NewDocumentCommand{\setarrayitem}{mmm}
 {
  \fparray_gset:cne { g_sandu_#1_fparray } { #2 } { #3 }
 }

\cs_generate_variant:Nn \fparray_new:Nn { c }
\cs_generate_variant:Nn \fparray_item:Nn { c }
\cs_generate_variant:Nn \fparray_gset:Nnn { cnn, cne }

\ExplSyntaxOff

\newarray{xx}
\readarray{xx}{1&2&3&4&5}

\newarray{yy}
\readarray{yy}{6&7&8&9&10}

\begin{document}

\begin{tabular}{cccc}
No & xx & yy & zz   \\ \hline
1 & \xx{1} & \yy{1} &  \fpeval{(\xx{1}+\yy{1})/2}  \\
2 & \xx{2} & \yy{2} &  \fpeval{(\xx{2}+\yy{2})/2}  \\
3 & \xx{3} & \yy{3} &    \\
4 & \xx{4} & \yy{4} &    \\
5 & \xx{5} & \yy{5} &    \\ \hline
\end{tabular}

\newarray{zz}

\bigskip

\newcount\counter
\counter=5
\loop
  \setarrayitem{zz}{\counter}{\fpeval{(\xx{\counter}+\yy{\counter})/2}}
  \advance \counter by -1
  \unless\ifnum \counter<1
\repeat

\begin{tabular}{cccc}
No & xx & yy & zz   \\ \hline
1 & \xx{1} & \yy{1} &  \zz{1} \\
2 & \xx{2} & \yy{2} &  \zz{2} \\
3 & \xx{3} & \yy{3} &  \zz{3} \\
4 & \xx{4} & \yy{4} &  \zz{4} \\
5 & \xx{5} & \yy{5} &  \zz{5} \\ \hline
\end{tabular}

\end{document}

enter image description here

egreg
  • 1,121,712
1

I did not really try to make your example work but would like to propose an alternative way of doing what I think you want to do.

\documentclass{beamer}
\usepackage{pgfmath}

\begin{document}

\def\xx{{1,2,3,4,5}}
\def\yy{{6,7,8,9,10}}

\newcommand{\Parse}[1]{\pgfmathparse{#1}\pgfmathresult}

\begin{frame}
\begin{table}[]
\begin{tabular}{cccc}
No & xx & yy & zz   \\ \hline
1 & \Parse{\xx[0]} & \Parse{\yy[0]} & \Parse{\xx[0]/2+\yy[0]/2}\\ 
2 & \Parse{\xx[1]} & \Parse{\yy[1]} & \Parse{\xx[1]/2+\yy[1]/2}\\ 
3 & \Parse{\xx[2]} & \Parse{\yy[2]} & \Parse{\xx[2]/2+\yy[2]/2}\\ 
4 & \Parse{\xx[3]} & \Parse{\yy[3]} & \Parse{\xx[3]/2+\yy[3]/2}\\ 
5 & \Parse{\xx[4]} & \Parse{\yy[4]} & \Parse{\xx[4]/2+\yy[4]/2}\\ 
\hline
\end{tabular}
\end{table}

\newcounter{counter}
\setcounter{counter}{4}
\loop
\Parse{\xx[\number\value{counter}]/2+\yy[\number\value{counter}]/2} 
\addtocounter{counter}{-1}
\unless\ifnum\number\value{counter}=-1
\repeat
\end{frame}
\end{document}

enter image description here

Of course you can also store the results in an array. (Note that I am using \foreach here which I find easier to deal with.

\documentclass{beamer}
\usepackage{pgfmath,pgffor}

\begin{document}

\def\xx{{1,2,3,4,5}}
\def\yy{{6,7,8,9,10}}

\newcommand{\Parse}[1]{\pgfmathparse{#1}\pgfmathresult}

\begin{frame}
\begin{table}[]
\begin{tabular}{cccc}
No & xx & yy & zz   \\ \hline
1 & \Parse{\xx[0]} & \Parse{\yy[0]} & \Parse{\xx[0]/2+\yy[0]/2}\\ 
2 & \Parse{\xx[1]} & \Parse{\yy[1]} & \Parse{\xx[1]/2+\yy[1]/2}\\ 
3 & \Parse{\xx[2]} & \Parse{\yy[2]} & \Parse{\xx[2]/2+\yy[2]/2}\\ 
4 & \Parse{\xx[3]} & \Parse{\yy[3]} & \Parse{\xx[3]/2+\yy[3]/2}\\ 
5 & \Parse{\xx[4]} & \Parse{\yy[4]} & \Parse{\xx[4]/2+\yy[4]/2}\\ 
\hline
\end{tabular}
\end{table}

\foreach \X in {4,3,...,0}
{%
 \pgfmathparse{\xx[\X]/2+\yy[\X]/2}
 \ifnum\X=4
    \xdef\zz{\pgfmathresult}
 \else
    \xdef\zz{\zz,\pgfmathresult}
 \fi     
}
\xdef\zz{{\zz}}
\Parse{\zz[2]}
\end{frame}
\end{document}
1

The listofitems package may give you at least some of what you need in terms of storing arrays.

\documentclass{beamer}
\usepackage{siunitx,amsmath,xparse,xfp}
\usepackage{listofitems}
\begin{document}
\setsepchar{&}
\readlist\xx{1&2&3&4&5}
\readlist\yy{6&7&8&9&10}
\begin{frame}[fragile]
\begin{table}[]
\begin{tabular}{cccc}
No & xx & yy & zz   \\ \hline
1 & \xx[1] & \yy[1] &  \fpeval{(\xx[1]+\yy[1])/2}  \\
2 & \xx[2] & \yy[2] &  \fpeval{(\xx[2]+\yy[2])/2}  \\
3 & \xx[3] & \yy[3] &    \\
4 & \xx[4] & \yy[4] &    \\
5 & \xx[5] & \yy[5] &    \\ \hline
\end{tabular}
\end{table}
\makeatletter
\def\tmp{}
\foreachitem\z\in\xx[]{%
  \ifnum\zcnt=1\relax\else\g@addto@macro\tmp{&}\fi%
  \edef\tmpA{\fpeval{(\z+\yy[\zcnt])/2}}%
  \expandafter\g@addto@macro\expandafter\tmp\expandafter{\tmpA}}
\makeatother
\readlist\zz{\tmp}
\foreachitem\z\in\zz[]{\zz[-\zcnt] }
\end{frame}
\end{document}

enter image description here