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.

While trying to make this problem more efficient I tried different methods and dabbled with making Greater and Equal Listable. To my surprise, while Greater worked as expected, Equal on the other hand showed a strange behavior. Let's dig deeper:

First let's look at Greater

Pick[#, DivisorSigma[1, #] > 2 #] &@Range[6]

Gives the error:

Pick::incomp: Expressions {1,2,3,4,5,6} and {1,3,4,7,6,12}>{2,4,6,8,10,12} have incompatible 
shapes. >>

Now we make Greater Listable

SetAttributes[Greater, Listable]

And we can now evaluate the above command successfully

Pick[#, DivisorSigma[1, #] > 2 #] &@Range[20]

{12, 18, 20}

Okay, let's move on to Equal

Pick[#, DivisorSigma[1, #] == 2 #] &@Range[8]

Sequence[]

We now make Equal Listable

SetAttributes[Equal, Listable]
Attributes[Equal]

{Listable, Protected}

Now let's try again:

Pick[#, DivisorSigma[1, #] == 2 #] &@Range[8]

Sequence[]

Hmmm, what's going on here?

Well, let's explicitly provide the list and see what happens:

Pick[{1, 2, 3, 4, 5, 6, 7, 8}, 
 DivisorSigma[1, {1, 2, 3, 4, 5, 6, 7, 8}] == 2 {1, 2, 3, 4, 5, 6, 7, 8}]

{6}

Interesting, this works!

okay now let's textually substitute using With, this should technically be the same thing right?

With[{p = Range[8]}, Pick[p, DivisorSigma[1, p] == 2*p]]

Sequence[]

I guess not.

Finally, let's look at Trace. I'll shorten the input list here.

First with explicit input of list:

Pick[{4, 5, 6}, DivisorSigma[1, {4, 5, 6}] == 2 {4, 5, 6}] // Trace

Mathematica graphics

Pick[Range[4, 6], DivisorSigma[1, Range[4, 6]] == 2 Range[4, 6]] // Trace

Mathematica graphics

We see that only in the explicit case does Equal act Listable What is going on here? Sorry about the tiny images.

share|improve this question
    
@PinguinDirk. I have a workaround that works if you look at my answer in the link. Just wondering why greater works but Equal doesn't work properly. –  RunnyKine Oct 21 '13 at 20:12
1  
I think this is related to this question. Range gives a packed array, for which Equal has special handling which bypasses the main evaluator. –  Simon Woods Oct 21 '13 at 20:16

1 Answer 1

up vote 1 down vote accepted

EDIT

My original answer posted below was a naive misunderstanding.

However,

For what its worth (apologies again for previous misconception):

SetAttributes[Equal, Listable]
Pick[#, Release@(Hold[DivisorSigma[1, #] == 2 #])] &@Range[8]

works...

OLD

Pick[#, DivisorSigma[1, #] == 2 #] &@Range[8]

your test applies to elements whereas you expect your Pick to apply to list. When you 'replace' # with list it works.

Note (for illustration purposes):

Function[x, Pick[x, DivisorSigma[1, #] == 2 # & /@ x]][Range[8]]

works.

In contrast the following works without modification:

Select[#, DivisorSigma[1, #] == 2 # &] &@Range[8]

or

Cases[#, _?(DivisorSigma[1, #] == 2 # &)] &@Range[8]
share|improve this answer
    
Actually, the point is that if you put the list explicitly it works. You can see that it works with Greater only when you make Greater Listable, note that I made Equal Listable. Also look at the Trace to see what's happening. –  RunnyKine Oct 22 '13 at 10:53
    
apologies, I take your point and as such have learned something, however i believe we are making the same point despite my poor explanation...when Greater is make listable the second argument of of Pick is a list of True,False from Pick will select. I apologise for not appreciating that you made Equal listable and hence your dilemma...rendering Equal listable for test produces desired list outside Pick but malfunctions inside Pick... –  ubpdqn Oct 22 '13 at 11:45

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.