3
$\begingroup$

I have a Sum expression:

s := Sum[2x,{x,0,3}]

As an exercise to explore the rewriting capabilities of the Wolfram Language, I would like to collect the result, and the different terms of the summation without changing the definition of the expression. Something like that:

{12,{0,2,4,6}}

The exact output format is not critical, as long as I have both the result, and the individual terms of the summation. After a fair amount of time, I end up with a solution I post as an answer below. But it seems quite convoluted to me. Would you find a simpler solution to achieve my goal?

$\endgroup$
  • 1
    $\begingroup$ If I may, this smacks of an XY problem to me, especially the “without changing the definition of s” requirement. Why do you want to do this? Perhaps reformulating the problem in whose context this came up might sidestep this issue entirely. $\endgroup$ – MarcoB Dec 10 '19 at 4:48
  • $\begingroup$ @MarcoB As you know it now, I'm in the process of learning the Wolfram Language. This is a self-assigned exercise to explore with the expression rewriting capabilities of Mathematica. As mentioned in the question, I tried a couple of things before reaching a "working" solution. So I would have been curious to see how the community would solve such a problem without changing the rules $\endgroup$ – Sylvain Leroux Dec 10 '19 at 12:49
  • $\begingroup$ I rewrote the terms of the question to make it clear it was a self-assigned challenge. I also add the self-study tag. $\endgroup$ – Sylvain Leroux Dec 10 '19 at 12:56
9
$\begingroup$

Have you considered Block?

s := Sum[2 x, {x, 0, 3}]

{s, Block[{Sum = Table}, s]}
{12, {0, 2, 4, 6}}
$\endgroup$
  • 1
    $\begingroup$ Arghhh! So ... simple! I've already saw Block, but I didn't realize function names were symbols that could be rebound to something else. Mathematica is amazing! $\endgroup$ – Sylvain Leroux Dec 10 '19 at 14:14
3
$\begingroup$

If evaluation of the term is okay, then you can use Trace

s := Sum[2 x, {x, 0, 3}]
With[{seq = Trace@s}, {seq[[-1]], Cases[seq, x : {__} :> x[[-1]]]}] // ReleaseHold

{12, {0, 2, 4, 6}}

$\endgroup$
3
$\begingroup$

I would do it this way:

t = Table[2 x, {x, 0, 3}];
{Total[t], t}

{12, {0, 2, 4, 6}}

But if you really want to keep s fixed, you could do:

Trace[s][[All, -1]]

which gives you the terms you are looking for, though with the "12" repeated a couple of times.

$\endgroup$
  • $\begingroup$ Thanks, @Bill. But, as stated in the question, "I don't want to change the definition of the summation s." Actually, this was a self-assigned exercise to learn about the Wolfram Language rewriting capabilities. I posted the question late in the evening, and I only realized this morning my intents were not clear. I rewrote the question to make that explicit. Sorry for having wasted your time. BTW, thank you too for having mentioned Trace, a new tool in my toolbox ;) $\endgroup$ – Sylvain Leroux Dec 10 '19 at 13:09
  • 1
    $\begingroup$ Trace gives you (more or less) what you asked for. My first comment was meant to suggest that using := and Sum that way is probably not the best approach since it locks you into some odd constructs later on. But I guess you knew this already! $\endgroup$ – bill s Dec 10 '19 at 14:44
  • $\begingroup$ No problem @bill. That's how I understood it. And my wording wasn't that clear anyway. $\endgroup$ – Sylvain Leroux Dec 10 '19 at 14:48
2
$\begingroup$

If the sum is not complicated, then why not use a more direct brute force approach?

{Sum[2 x, {x, 0, 3}], Table[2 x, {x, 0, 3}]}

or

#[2 x, {x, 0, 3}] & /@ {Sum, Table}
$\endgroup$
  • $\begingroup$ Thanks, Jim. But, as stated in the question, "I don't want to change the definition of the summation s." Actually, this was a self-assigned exercise to learn about the Wolfram Language rewriting capabilities. I posted the question late in the evening, and I only realized this morning my intents were not clear. I rewrote the question to make that explicit. Sorry for having wasted your time. $\endgroup$ – Sylvain Leroux Dec 10 '19 at 13:10
  • 1
    $\begingroup$ Time wasn't wasted especially as the other answers show how many different ways Mathematica can solve a problem. $\endgroup$ – JimB Dec 10 '19 at 15:21
2
$\begingroup$

You may use Reapand Sow.

ClearAll[sumTerms]
SetAttributes[sumTerms, HoldFirst]
sumTerms[sumSym_Symbol] :=
 Module[{ov = First@OwnValues[sumSym]},
  Values[ov /. Sum[f_, p__] :> Reap[Sum[Sow[f], p]]]
  ]

Then with

s := Sum[2 x, {x, 0, 3}]

sumTerms[s]
{12, {{0, 2, 4, 6}}}

or

p := Sum[2 x + y, {x, 0, 3}, {y, -10, -8}]

sumTerms[p]
{-72, {{-10, -9, -8, -8, -7, -6, -6, -5, -4, -4, -3, -2}}}

Hope this helps.

$\endgroup$
  • $\begingroup$ Thank you very much, @Edmund. I have a hard time understanding Values[ov /. Sum[f_, p__] :> Reap[Sum[Sow[f], p]]] I understand it's a rewriting rule but the pattern is puzzling me. Could you elaborate a little on that? $\endgroup$ – Sylvain Leroux Dec 10 '19 at 13:02
  • 1
    $\begingroup$ @SylvainLeroux I recommend the Patterns overview in the docs. The bits used above are shorthand ReplaceAll, Blank and friends, and RuleDelayed. $\endgroup$ – Edmund Dec 10 '19 at 13:18
  • $\begingroup$ Actually, I missed the second use case for the Values function: " Values[{key1val1,key2val2,…}] : gives a list of the vali in a list of rules. " Things are clear now! $\endgroup$ – Sylvain Leroux Dec 10 '19 at 13:30
2
$\begingroup$

I would go this way.

{Total[2 #], 2 #}&@Range[0, 3]

{12, {0, 2, 4, 6}}

$\endgroup$
  • $\begingroup$ Thanks, Okkes. But, as stated in the question, "I don't want to change the definition of the summation s." Actually, this was a self-assigned exercise to learn about the Wolfram Language rewriting capabilities. I posted the question late in the evening, and I only realized this morning my intents were not clear. I rewrote the question to make that explicit. Sorry for having wasted your time. $\endgroup$ – Sylvain Leroux Dec 10 '19 at 13:11
  • $\begingroup$ +1 To avoid doing the multiplications twice: {Total[#], #} &[2 Range[0, 3]] $\endgroup$ – Bob Hanlon Dec 10 '19 at 15:35
1
$\begingroup$
Reap[ReleaseHold[#1]]& @@ 
    ( OwnValues[s] /. (_ :>Sum[a_,b_]) -> Hold[Sum[Sow[a],b]])
{12,{{0,2,4,6}}}

The idea is the rewrite the OwnValues associated with the symbol s to inject the Sow function around the expression in the sum. Finally, the modified sum is evaluated inside a Reap function to collect both the result and the individual terms "raised" by the Sow function.

I won't claim this is an optimal solution. It is merely the result of many trials and errors, especially because I had a hard time dealing with Hold'ed expressions.

$\endgroup$

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.