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.

My first question here as I only got into Mathematica programming recently. Basically I have a large symbolic algebraic expression where I know certain variables with head pε appear with degree 2 in each term. So the terms look like this:

(...) pε[i, j] pε[k, l] + (...) pε[m ,n] pε[p, q] + ...

I want to pick out which of these appear in my expression, and I figured out this would do the trick

(Reap[expr /. patt : (x_pe y_pe | _pe _pe) :> Sow[patt] ;][[2,1]]) // DeleteDuplicates

which gives:

{pe[4, 6]^2, pe[3, 6]^2, pe[2, 6]^2, pe[5, 6]^2, pe[3, 6] pe[4, 6], pe[3, 6] pe[5, 6], pe[4, 6] pe[5, 6]}

This however is missing terms because, when I ran two sets of pattern matches without |, I get more terms

(Reap[expr /. patt : x_pe y_pe :> Sow[patt] ; 
expr /. patt : _pe _pe :> Sow[patt] ;][[2,1]]) // DeleteDuplicates

{pe[3, 6] pe[4, 6], pe[2, 6] pe[4, 6], pe[2, 6] pe[3, 6], pe[3, 6] pe[5, 6], pe[4, 6] pe[5, 6], pe[2, 6] pe[5, 6], pe[4, 6]^2, pe[3, 6]^2, pe[2, 6]^2, pe[5, 6]^2}

So I would like to know what's going on. In particular I imagine the first would be a lot more efficient if it worked properly.

Also feel free to give alternative ways of doing this. My choice of using Reap, Sow was one of efficiency but my of knowledge of the language is still small.

Edit

Based on the example given by @Federico I have constructed a small analogue where the difficulties are manifest, I use Cases because it's conceptually clearer

sum = Sum[pe[i, j] l[i, j] pe[j, k], {i, 3}, {j, 3}, {k, 3}]

whose output is:

l[1, 1] pe[1, 1]^2 + l[1, 1] pe[1, 1] pe[1, 2] + l[1, 1] pe[1, 1] pe[1, 3] + l[2, 1] pe[1, 1] pe[2, 1] + l[1, 2] pe[1, 2] pe[2, 1] + l[2, 1] pe[1, 2] pe[2, 1] + l[2, 1] pe[1, 3] pe[2, 1] + l[1, 2] pe[1, 2] pe[2, 2] + l[2, 2] pe[2, 1] pe[2, 2] + l[2, 2] pe[2, 2]^2 + l[1, 2] pe[1, 2] pe[2, 3] + l[2, 2] pe[2, 2] pe[2, 3] + l[3, 1] pe[1, 1] pe[3, 1] + l[3, 1] pe[1, 2] pe[3, 1] + l[1, 3] pe[1, 3] pe[3, 1] + l[3, 1] pe[1, 3] pe[3, 1] + l[2, 3] pe[2, 3] pe[3, 1] + l[1, 3] pe[1, 3] pe[3, 2] + l[3, 2] pe[2, 1] pe[3, 2] + l[3, 2] pe[2, 2] pe[3, 2] + l[2, 3] pe[2, 3] pe[3, 2] + l[3, 2] pe[2, 3] pe[3, 2] + l[1, 3] pe[1, 3] pe[3, 3] + l[2, 3] pe[2, 3] pe[3, 3] + l[3, 3] pe[3, 1] pe[3, 3] + l[3, 3] pe[3, 2] pe[3, 3] + l[3, 3] pe[3, 3]^2

So there are two types of terms those that contain pe squared and those that don't. Those that do are captured by

Cases[sum, _pe^2, Infinity]

those that don't require

Cases[sum, _ x_pe y_pe -> x y, Infinity]

So the question now is why does the following also work for the case with no pe squared?

(Reap[sum /. patt : (x_pe y_pe) :> Sow[patt]; ][[2,1]])

And a followup question, how would one capture the squared terms if Mathematica didn't collect them in a square? For example, if I had pe[1, 1]l[1, 1] pe[1, 1] can I construct a pattern to capture this? Or will it never happen due to Times having the Orderless attribute? I am thinking of a situation where l[1,1] is very large and Mathematica doeesn't order it.

Another question is can I combine both pattern matching cases in one with the use of |, and, if so, would that be more efficient?

share|improve this question
    
Please include your expr in the question. –  Mr.Wizard Mar 27 '13 at 4:43
add comment

1 Answer

sum = Sum[pe[i, j] pe[j, k], {i, 3}, {j, 3}, {k, 3}]
Cases[sum, HoldPattern[_pe*_pe | _pe^2], Infinity]

Note that patterns are first evaluated, so, if you omit HoldPattern, _pe*_pe | _pe^2 becomes _pe^2 | _pe^2, which is not what you want.

share|improve this answer
    
Thanks for the reply but it doesn't seem to be working I have tried (Reap[expr /. HoldPattern[patt : (_pe _pe | _pe^2)] :> Sow[patt] ;][[2, 1]]) // DeleteDuplicates (Reap[expr /. patt : HoldPattern[(_pe _pe | _pe^2)] :> Sow[patt] ;][[2, 1]]) // DeleteDuplicates (Reap[expr /. patt : (HoldPattern[_pe _pe] | _pe^2) :> Sow[patt] ;][[2, 1]]) // DeleteDuplicates they all return the first result I gave with missing entries. I am guessing the problem comes with how | interacts with patt: –  Eduardo Serna Mar 26 '13 at 18:08
    
Why doesn't it work? It seems ok to me. The code you posted in the comment above is a mess... :/ –  Federico Mar 26 '13 at 18:11
    
Sorry was trying to format it properly but it doesn't seem to work in the commenting section. My issue is that my sum are terms that multiply the bits with _pe which I am trying to collect separately, your example with cases doesn't work with my expression as is. –  Eduardo Serna Mar 26 '13 at 18:17
    
Nevermind, got your solution to work, thanks so much!!! –  Eduardo Serna Mar 26 '13 at 18:21
    
ALthough I am still confused why my original attempt doesn't work –  Eduardo Serna Mar 26 '13 at 18:22
show 2 more comments

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.