3
$\begingroup$

Here is a minimal example:

s = 1 /(a + b[3]) + 1 /(2 a + b[3]);
s[[1]] = Sum[s[[1]] /. b[3] -> k, {k, 3}]
s[[4]]
s[[4]] = Sum[s[[4]] /. b[3] -> k, {k, 3}]

Output:

Out[143]= 1/(1 + a) + 1/(2 + a) + 1/(3 + a)
Out[144]= 1/(2 a + b[3])

Set::partw: Part 4 of (1/(1+a)+1/(2+a)+1/(3+a))+1/(2 a+b[3]) does not exist. >>

Out[145]= 1/(1 + 2 a) + 1/(2 + 2 a) + 1/(3 + 2 a)

I could only make the error occur when using Set. As the above code shows, both s[[4]] and Sum[s[[4]] /. b[3] -> k, {k, 3}] are well defined.

I have been struggling with similar errors for days, can someone please explain exactly what is happening behind the scenes?

$\endgroup$
5
  • $\begingroup$ Use ReplacePart[s, 4 -> Sum[s[[4]] /. b[3] -> k, {k, 3}]] $\endgroup$
    – ciao
    Commented Jan 18, 2014 at 11:23
  • $\begingroup$ If you evaluate s=s before evaluating s[[4]] = Sum[s[[4]] /. b[3] -> k, {k, 3}], the problem disappears $\endgroup$
    – andre314
    Commented Jan 18, 2014 at 12:12
  • $\begingroup$ Thanks @rasher, there are a few different workarounds. However they are not optimal and do not behave the same as Part. For ex: ReplaceParts[s,{}-> x] returns s unaltered. $\endgroup$
    – Art Gower
    Commented Jan 18, 2014 at 12:14
  • $\begingroup$ Hi @andre, wow s=s does work, but why!? Thanks $\endgroup$
    – Art Gower
    Commented Jan 18, 2014 at 12:19
  • $\begingroup$ @ArturGower: Well, yes. ReplacePart is a function, so you need to assign the result, as in s=ReplacePart.... I think your issue is just an interesting gotcha - part ([[]]) works on fullform expressions, and s vs s=s (which I noted when trying your code) gives the exact same fullform result. Beats me, perhaps L.S. or M.W. or other wizards will chime in. In any case, IMHO ReplacePart is the way to go working with expressions. $\endgroup$
    – ciao
    Commented Jan 18, 2014 at 12:35

1 Answer 1

3
$\begingroup$

The reason this error occurs is because Set and Part have the Attribute HoldFirst, while functions like Position, which was used to get the position 4, does not have HoldFirst.

To verify, the line

s[[1]] = Sum[s[[1]] /. b[3] -> k, {k, 3}]

adds a parenthesis which does not get evaluated, so

(s//Hold)[[1,4]]
Out[1] = Part::partw: "Part 4 of (1/(1+a)+1/(2+a)+1/(3+a))+1/(2\a+b[3]) does not exist."

where as using Evaluate will distribute the parenthesis (effectively distributing the function Plus)

(s//Evaluate //Hold)[[1,4]]
1/(2 a + b[3])

So as pointed out by @andre executing s=s before s[[4]]= ... would solve the problem.

I thank @andre and @rasher for their contributions.

$\endgroup$
2
  • $\begingroup$ +1 for the analysis - I thought it might be a hold, but was working on answering the bit-flip question elsewhere. Thanks for following up, it's a good example. $\endgroup$
    – ciao
    Commented Jan 18, 2014 at 12:56
  • $\begingroup$ You are right : s[[1]] = Sum[s[[1]] /. b[3] -> k, {k, 3}] adds a parenthesis which does not get evaluated. This can be seen if you evaluate Trace[s] : you see transformation of s from a 2 elements expression (with parenthesis) to a 4 elements expression. $\endgroup$
    – andre314
    Commented Jan 18, 2014 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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