Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question
    
Use ReplacePart[s, 4 -> Sum[s[[4]] /. b[3] -> k, {k, 3}]] –  rasher Jan 18 at 11:23
    
If you evaluate s=s before evaluating s[[4]] = Sum[s[[4]] /. b[3] -> k, {k, 3}], the problem disappears –  andre Jan 18 at 12:12
    
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. –  Artur Gower Jan 18 at 12:14
    
Hi @andre, wow s=s does work, but why!? Thanks –  Artur Gower Jan 18 at 12:19
    
@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. –  rasher Jan 18 at 12:35

1 Answer 1

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.

share|improve this answer
    
+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. –  rasher Jan 18 at 12:56
    
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. –  andre Jan 18 at 19:14

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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