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.

4
  • \partialsum{1} % should be 0: Shouldn't it be 3 (i.e., the first item in the sequence)? Jun 22, 2019 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, 2019 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, 2019 at 20:57
  • @KeksDose ahahah a little bit of everything.
    – noibe
    Jun 22, 2019 at 23:50

3 Answers 3

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

3
  • Should the sequence be private?
    – Joseph Wright
    Jun 22, 2019 at 17:20
  • @JosephWright Not necessarily, in my opinion.
    – egreg
    Jun 22, 2019 at 17:25
  • Fair enough: I was musing rather than asking for a change
    – Joseph Wright
    Jun 22, 2019 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.