Skip to main content
4 of 4
added 1449 characters in body
Mr.Wizard
  • 273.1k
  • 34
  • 595
  • 1.4k

If I understand you correctly, simply test if the maximum value in the list is Positive:

Positive @ Max @ a

Speed comparison with other methods that were posted:

timeAvg = 
  Function[func,
    Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}],
    HoldFirst];

a = RandomInteger[{-1*^7, 2}, 1*^7];

MemberQ[a, _?Positive] // timeAvg

Total@UnitStep[-a] =!= Length@a // timeAvg

Positive@Max@a // timeAvg

0.593

0.0624

0.01148


Early-exit methods

Although very fast, especially with packed lists, the method above does scan the entire list with no possibility for an early exit when a positive elements occurs near the front of the list. In that case a test that does not scan the entire list may be faster, such as the one that R.M posted. Exploring such methods I propose this:

! VectorQ[a, NonPositive]

Unlike MemberQ, VectorQ does not unpack a packed list.

Timings compared to MemberQ and Max, first with an early positive appearance:

SeedRandom[1]
a = RandomReal[{-1*^7, 1000}, 1*^7];

Positive @ Max @ a        // timeAvg
! VectorQ[a, NonPositive] // timeAvg
MemberQ[a, _?Positive]    // timeAvg
0.008736

0.00013984

0.2528

(Most of the MemberQ time is spent unpacking the list.)

Then no positive appearance (full scan):

a = RandomInteger[{-1*^7, 0}, 1*^7];

Positive @ Max @ a        // timeAvg
! VectorQ[a, NonPositive] // timeAvg
MemberQ[a, _?Positive]    // timeAvg
0.01148

1.544

2.528

Finally a mid-range appearance of a positive value in an unpacked list:

a = RandomReal[{-50, 0}, 1*^7];
a[[5*^6]] = 1;

Positive @ Max @ a        // timeAvg
! VectorQ[a, NonPositive] // timeAvg
MemberQ[a, _?Positive]    // timeAvg
0.212

0.702

1.045
Mr.Wizard
  • 273.1k
  • 34
  • 595
  • 1.4k