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.

I have to following code that solves a problem for me. The example that is given to us is as follows: lst = {1,-2, 3, 4,5,-3, -4, 9,7,0,8}, predicate = Positive. The maximal Predicate-segments of lst are {1}, {3,4,5}, {9,7}, and {8}.

getSegments[lst_,predicate_] :=
  Module[{res= {},seg, lstcopy=lst},
    While[Length[lstcopy]>0,
      seg = TakeWhile[lstcopy,predicate[#]&];
      If[Length[seg] > 0,
        (* True *)
        AppendTo[res,seg]; 
        lstcopy=Drop[lstcopy,Length[seg]],
        (* False *)
        lstcopy=Drop[lstcopy,Length[TakeWhile[lstcopy,!predicate[#]&]]]; 
      ] (* If *)
    ] ;(* While *)
    Return[res];
  ];

The above code works fine for the following input:

In[1]:= getSegments[RandomInteger[{-100,100},10],Positive]
Out[1]= {{68,13},{59},{16},{41}}

In[2]:= getSegments[RandomInteger[{-100,100},10],Negative]
Out[2]= {{-26},{-77,-60},{-11,-78}}

Yet something very strange happens with the following:

In[3]:= getSegments[RandomInteger[{1,2},10],EvenQ]
Out[3]= {}

In[4]:= getSegments[{1,1,2,2,1,2,2,1,2,2},EvenQ]
Out[4]= {{2,2},{2,2},{2,2}}

This is the same for OddQ.

Why does it treat the RandomInteger result so differently from the list?

The input for In[4] is also generated with a call to RandomInteger[{1,2},10]. I did find that seg is always empty with the In[3] case, while the False branch of the If takes all the elements in the list.

EDIT It is of note that I run Mathematica 8 on Linux. The above works fine on Windows versions of Mathematica.

EDIT 2

In[76]:= getSegments[RandomInteger[{1,2},5],EvenQ] // Trace
Out[76]= {{RandomInteger[{1,2},5],
{1,2,1,2,1}},getSegments[{1,2,1,2,1},EvenQ],SplitBy[{1,2,1,2,1},EvenQ]
[[If[EvenQ[First[{1,2,1,2,1}]],1,2];;All;;2]],
{SplitBy[{1,2,1,2,1},EvenQ],Split[{1,2,1,2,1},EvenQ[#1]===EvenQ[#2]&],
{(EvenQ[#1]===EvenQ[#2]&)[1,2],EvenQ[1]===EvenQ[2],{EvenQ[1],False},
{EvenQ[2],True},False===True,False},{(EvenQ[#1]===EvenQ[#2]&)
[2,1],EvenQ[2]===EvenQ[1],{EvenQ[2],True},
{EvenQ[1],False},True===False,False},{(EvenQ[#1]===EvenQ[#2]&)
[1,2],EvenQ[1]===EvenQ[2],{EvenQ[1],False},
{EvenQ[2],True},False===True,False},{(EvenQ[#1]===EvenQ[#2]&)
[2,1],EvenQ[2]===EvenQ[1],{EvenQ[2],True},
{EvenQ[1],False},True===False,False},{{1},{2},{1},{2},{1}}},
{{{{First[{1,2,1,2,1}],1},EvenQ[1],False},If[False,1,2],2},2;;All;;2},
{{1},{2},{1},{2},{1}}[[2;;All;;2]],{{2},{2}}}

I've trimmed down to problem to the following:

lst = RandomInteger[{1, 2}, 10]
TakeWhile[lst, EvenQ]
TakeWhile[lst, OddQ]

One of the TakeWhile calls should always return some value. Yet they both give an empty list. This works fine on Windows, yet fails on Linux.

share|improve this question
1  
getSegments[RandomInteger[{1,2},10], EvenQ] works as expected on my system (Mma v8.0.4 Windows Vista 64bit). –  kguler Dec 20 '12 at 10:58
    
@kguler Yes, I've tried that too and see that it works on Windows. It seems to be a Linux specific problem. –  Willem Dec 20 '12 at 11:02
1  
I found an older question that relates to this. It's apparently a known bug in version 8.0.0 so I'm adding those tags. –  Mr.Wizard Dec 20 '12 at 11:42
add comment

1 Answer 1

up vote 4 down vote accepted

I don't know why it doesn't work on your system (it does mine), but perhaps this will help:

getSegments[lst_, test_] := 
  SplitBy[lst, test][[ If[test @ First @ lst, 1, 2] ;; ;; 2 ]]

getSegments[{1, -2, 3, 4, 5, -3, -4, 9, 7, 0, 8}, Positive]
{{1}, {3, 4, 5}, {9, 7}, {8}}

I found an older question that relates to this. It's apparently a known bug in version 8.0.0.
You will need to unpack your data before passing it to TakeWhile.

lst = RandomInteger[{1, 2}, 10];

TakeWhile[Developer`FromPackedArray @ lst, EvenQ]
share|improve this answer
    
While that does solve the problem (not to mention in a much nicer way :)), it does not give me an answer to my problem. –  Willem Dec 20 '12 at 11:19
1  
@Willem I wish I had an answer for you other than "could not reproduce" but I'm using Windows. Would you append the output of getSegments[RandomInteger[{1, 2}, 10], EvenQ] // Trace on your system to the question? –  Mr.Wizard Dec 20 '12 at 11:24
    
I've added the Trace result. I also trimmed down the problem to just the TakeWhile. –  Willem Dec 20 '12 at 11:34
    
@Willem sorry, I wasn't clear; I meant your getSegments, but I see that you've isolated the problem to TakeWhile. I now suspect packing. Please try: lst = Developer`FromPackedArray@RandomInteger[{1, 2}, 10]; then TakeWhile[lst, EvenQ] and TakeWhile[lst, OddQ] and report if then works correctly. –  Mr.Wizard Dec 20 '12 at 11:38
    
Impressive, that solved the problem. If you could add that to your answer then I will accept your answer. –  Willem Dec 20 '12 at 11:46
add comment

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.