# In Mathematica 9, how do I check if all list members are True?

Posted 5 months ago
1879 Views
|
16 Replies
|
5 Total Likes
|
 Seems like maybe Mathematica 9 didn't have AllTrue[] function.Anyway, I'm working with Pascal's triangle, trying to see if all members [except first/last] are divisible by the row number. I create a list or members, a list of divisibilities [evaluates to true/false].But then I want to check the list of disvisibilities for ALL being True, which is what I'm really looking for.So, I want to evaluate a variable that has a list of boolean true/false values and evaluate if all members are "true" [I suppose I could also evaluate if 'any' are False, but I'd prefer "all true"].So, how would I go about that without the AllTrue[] function, which I'm guessing was added in a later revision?Seems like this should be a fairly trivial thing? But not sure how to go about it?I mean, I guess I could go the opposite route and say something like: VariableNameHere=MemberQ[{ListNameVariable},False] IE, check whether false is a member, in which case the entire list isn't divisible by the row number.But I'd rather directly check that all members are True, as opposed to back@wardly checking whether any member is false.So, is there some simpler way to check for "AllTrue" without the AllTrue[] function?
16 Replies
Sort By:
Posted 5 months ago
 Well, here's my first pass at a ridiculously stupid workaround: SomePrimeCandidate = 191; PascalStart = 1; PascalEnd = Ceiling[(SomePrimeCandidate - 1)/2]; PascalRange = Range[PascalStart, PascalEnd]; PascalRow = Factorial[SomePrimeCandidate]/((Factorial[(SomePrimeCandidate-PascalRange)])*(Factorial[PascalRange])); PascalDivisibility = Divisible[PascalRow, SomePrimeCandidate]; IsComposite = MemberQ[PascalDivisibility, False]; IsPrime = (IsComposite == False) PascalDivisibilityArray = Transpose[{PascalRow, PascalDivisibility}]; PascalDivisibilityGrid = Grid[PascalDivisibilityArray] 
Posted 5 months ago
 As you can see, I simply took the row divisibility-by-row-number list ad did a MemberQ check versus "False," and then Simply did a check whether the check is false or not, which returns true if false, or false if true, to "invert" the value.Ridiculous workaround. But, as long as it works, right? :PSeriously though, is there an easier way to check that all list members are specifically true as opposed to "no members are false"?I feel like there should be, save for the fact AllTrue[] apparently wasn't a thing in Mathematica 9 (I know, I'm a few versions back; been meaning to upgrade for a while, just haven't gotten around to it yet).
Posted 5 months ago
 Hi Michael,You can use pattern matching listTF = {True, False, False, True}; listT = {True, True, True, True}; listTF // MatchQ[{True ..}] (* False *) listT // MatchQ[{True ..}] (* True *) Combine that with mapping a predicate function allTrue[list_, test_] := test /@ list // MatchQ[{True ..}] allTrue[{2, 3, 4, 6, 8}, EvenQ] (* False *) allTrue[{2, 4, 6, 8}, EvenQ] (* True *) 
Posted 5 months ago
 Interesting, if a bit more ... complicated. [My kludge-y solution got it done in basically 2 lines with MemberQ[list, False] and then simply doing a check whether the output is "[Output]==False" to flip the output bit from False to True. ;) ]
Posted 5 months ago
 What about using And@@? Something like And @@ EvenQ /@ {2,4,6} ?
Posted 5 months ago
 This is clearly the most Wolframian way of doing it, perhaps faster is And @@, but harder to read perhaps…
Posted 5 months ago
 The suggestions so far miss the efficiency of AllTrue , that it stops checking the solutions at the first failure. So AllTrue[{1,2,3,4,5,6,7}, OddQ] is only going to evaluate OddQ twice, and will stop trying at that point. Something like this would work I think: allTrue[list_, test_] := Catch[ Map[Function[If[!test @ #, Throw[False]]], list]; True ] 
Posted 5 months ago
 Careful. For conjunctions, Mathematica performs a short circuit evaluation, i.e. it stops anding up Booleans as soon as it encounters false. Btw this is standard procedure for any modern programming languages.
Posted 5 months ago
 This might be relevant. From the documentation reference of And:As I see it, the OP had a list consisting of only True or False and wanted to see if all elements were True. The additional condition of OddQ somehow crept in later in the discussion.
Posted 5 months ago
 I think Jason's point is that AllTrue short-circuits the Map. However, the timings suggest that it is slower. What am I missing? test1 = {1}~Join~ConstantArray[2, 10^6]; test2 = ConstantArray[2, 10^6]~Join~{1}; allTrue[list_, test_] := test /@ list // MatchQ[{True ..}] allTrueJason[list_, test_] := Catch[Map[Function[If[! test@#, Throw[False]]], list]; True] allTrue[test1, OddQ] // AbsoluteTiming (* {0.204723, False} *) allTrueJason[test1, OddQ] // AbsoluteTiming (* {0.461795, False} *) Similar timings for test2.
Posted 5 months ago
 Map (/@) will probably get compiled for large lists, so that could explain the difference…
Posted 5 months ago
 Jason is right; it doesn't short circuit. You see the difference in And @@ ((Print[#]; EvenQ[#]) & /@ {2, 4, 6, 1, 3, 5}) versus AllTrue[{2, 4, 6, 1, 3, 5}, (Print[#]; EvenQ[#]) &] This shatters illusions.
Posted 5 months ago
 Obviously, this will not short circuit, it will first map everything and then apply the And operator.You would have to do this: And[Print[2]; EvenQ[2], Print[4]; EvenQ[4], Print[6]; EvenQ[6], Print[1]; EvenQ[1], Print[3]; EvenQ[3], Print[5]; EvenQ[5]] 2 4 6 1 False 
Posted 5 months ago
 I think the point is, if you already have a list of boolean values,  list = {True, False, False, ....}  then  And @@ list  is absolutely the right thing to do. AllTrue or any of the v9 implementations of it listed above would be overkill.
 Jason,Agreed. Do you have any idea why the allTrue implementation you provided, that attempts to short-circuit Map, does not perform as expected?
 It performs exactly as I would expect. In some cases the test you wish to run is very fast, so that it is faster to run that test on all the inputs and check the results after than it is to do the incremental checks needed for the short circuit.As mentioned above, OddQ is written in low-level kernel code and is optimised when mapped: In[13]:= list = RandomInteger[100, 10^6]; In[14]:= First@RepeatedTiming[OddQ /@ list] Out[14]= 0.21808 In[15]:= oddQ[x_] := OddQ[x]; In[16]:= First@RepeatedTiming[oddQ /@ list] Out[16]= 0.524905 But if running your predicate function is not as fast as OddQ then you do want to use avoid applying it to all elements of the list if possible.Lastly, OddQ is listable, so you can be even faster by avoiding map: In[17]:= First@RepeatedTiming[OddQ@list] Out[17]= 0.0154204