Discrepancy with TakeWhile between RandomInteger result and list on Linux

5

Bug introduced in 8.0.0 and fixed in 8.0.1


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.

Chrono

Posted 2012-12-20T10:11:25.787

Reputation: 215

1getSegments[RandomInteger[{1,2},10], EvenQ] works as expected on my system (Mma v8.0.4 Windows Vista 64bit). – kglr – 2012-12-20T10:58:21.043

@kguler Yes, I've tried that too and see that it works on Windows. It seems to be a Linux specific problem. – Chrono – 2012-12-20T11:02:27.130

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 – 2012-12-20T11:42:02.677

Answers

5

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]

Mr.Wizard

Posted 2012-12-20T10:11:25.787

Reputation: 259 163

While that does solve the problem (not to mention in a much nicer way :)), it does not give me an answer to my problem. – Chrono – 2012-12-20T11:19:37.117

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 – 2012-12-20T11:24:15.183

I've added the Trace result. I also trimmed down the problem to just the TakeWhile. – Chrono – 2012-12-20T11:34:52.903

@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 – 2012-12-20T11:38:19.823