5

How can I compute the partial sum of a sequence of integers? This is what I have so far

\documentclass{article}
\usepackage{calc, forloop, xparse}

\ExplSyntaxOn
\seq_new:N \g_tmp_seq
\seq_new:N \g_partialsum_seq
\seq_set_from_clist:Nn \g_tmp_seq {3, 1, 2, 4, 0, 1}

\newcounter{i}
\newcounter{j}
\newcounter{lengthplusone}
\setcounter{lengthplusone}{\seq_count:N \g_tmp_seq + 1}

\forloop{i}{1}{ \value{i} < \value{lengthplusone} }{
  \seq_gput_right:Nn \g_partialsum_seq {0
    \forloop{j}{1}{ \value{j} < \value{i} }{
      + \seq_item:Nn \g_tmp_seq { \value{j} - 1}
    }
  }
}

\cs_new:Npn \partialsum #1 {
  \seq_item:Nn \g_partialsum_seq { #1 }
}
\ExplSyntaxOff

\begin{document}
\partialsum{1} % should be 0

\partialsum{2} % should be 3

\partialsum{3} % should be 4

\partialsum{4} % should be 6

\partialsum{5} % should be 10

\partialsum{6} % should be 10
\end{document}

Unfortunately the sum doesn't get expanded, plus all the values of \partialsum are equal to the last summation.

  • \partialsum{1} % should be 0: Shouldn't it be 3 (i.e., the first item in the sequence)? – Phelype Oleinik Jun 22 '19 at 12:55
  • No, I need it to be \partialsum{n} = \sum_{i = 1}^{n - 1} \g_tmp_seq{i} for n > 1 and \partialsum{1} = 0. – noibe Jun 22 '19 at 13:01
  • @noibe I have been looking into the 51 questions you have been asking since last October (2018). What are you doing? – Keks Dose Jun 22 '19 at 20:57
  • @KeksDose ahahah a little bit of everything. – noibe Jun 22 '19 at 23:50
5

It's more natural to use expl3 iteration over the seq I think:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\seq_new:N \g_tmp_seq
\seq_new:N \g_partialsum_seq
\seq_set_from_clist:Nn \g_tmp_seq {3, 1, 2, 4, 0, 1}
\seq_set_from_clist:Nn \g_partialsum_seq {0}
\tl_new:N\l_sum

\seq_map_inline:Nn\g_tmp_seq{
  \tl_set:Nx\l_sum{\int_eval:n{\l_sum+#1}}
  \seq_gput_right:NV \g_partialsum_seq \l_sum
}

\NewDocumentCommand\partialsum {m}{
  \seq_item:Nn \g_partialsum_seq { #1 }
}
\ExplSyntaxOff

\begin{document}
\partialsum{1} % should be 0

\partialsum{2} % should be 3

\partialsum{3} % should be 4

\partialsum{4} % should be 6

\partialsum{5} % should be 10

\partialsum{6} % should be 10
\end{document}
5

I dropped calc and forloop entirely, as you can do everything using plain expl3. As a bonus you can make the command expandable and have an optional argument to set the starting point of the summation.

The major difference from your version is that the code doesn't store the summed sequence. Each time the command is used the summation is done for the selected interval.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \g_noibe_numbers_seq
\seq_set_from_clist:Nn \g_noibe_numbers_seq {3, 1, 2, 4, 0, 1}
\NewExpandableDocumentCommand \partialsum { O{1} m }
  { \__noibe_partialsum:Nnnn \g_noibe_numbers_seq {#1-2} {#2-2} { } }
\cs_new:Npn \__noibe_partialsum:Nnnn #1 #2 #3 #4
  {
    \int_compare:nNnTF {#2} > {#3}
      { \int_eval:n {#4 0} }
      {
        \exp_args:Nf
        \__noibe_partialsum:nN { \int_eval:n {#2+1} } #1
          {#4} {#3}
      }
  }
\cs_new:Npn \__noibe_partialsum:nN #1 #2
  {
    \exp_args:Nf
    \__noibe_partialsum:nnNnn { \seq_item:Nn #2 {#1} + } {#1} #2
  }
\cs_new:Npn \__noibe_partialsum:nnNnn #1 #2 #3 #4 #5
  { \__noibe_partialsum:Nnnn #3 {#2} {#5} {#4#1} }
\ExplSyntaxOff
\begin{document}
\partialsum{1} % should be 0

\partialsum{2} % should be 3

\partialsum{3} % should be 4

\partialsum{4} % should be 6

\partialsum{5} % should be 10

\partialsum{6} % should be 10

\ifnum\partialsum{5}=\partialsum{6}
  The fifth item is zero.
\else
  The fifth item is nonzero.
\fi
\end{document}
4

Much less code with expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\setsequence}{m}
 {% #1 = items
  \seq_set_from_clist:Nn \l_noibe_sequence_seq { #1 }
 }

\NewExpandableDocumentCommand{\partialsum}{m}
 {% #1 = (one more than the) number of items to sum
  \int_eval:n
   { 
    0 \int_step_function:nN { #1 - 1 } \__noibe_sequence_sum:n
   }
 }

\cs_new:Nn \__noibe_sequence_sum:n
 {
  \int_compare:nF { #1 > \seq_count:N \l_noibe_sequence_seq }
   {
    + \seq_item:Nn \l_noibe_sequence_seq { #1 }
   }
 }
\ExplSyntaxOff

\begin{document}

\setsequence{3, 1, 2, 4, 0, 1}

\partialsum{1} --- should be 0

\partialsum{2} --- should be 3

\partialsum{3} --- should be 4

\partialsum{4} --- should be 6

\partialsum{5} --- should be 10

\partialsum{6} --- should be 10

\partialsum{7} --- should be 11

\partialsum{8} --- should be 11

\end{document}

enter image description here

  • Should the sequence be private? – Joseph Wright Jun 22 '19 at 17:20
  • @JosephWright Not necessarily, in my opinion. – egreg Jun 22 '19 at 17:25
  • Fair enough: I was musing rather than asking for a change – Joseph Wright Jun 22 '19 at 17:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.