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 a rank 3 matrix:

r = {{{1, 10}, {19, 71}, {111, 159}}, {{1, 5}, {25, 63}, {118, 132}, {164, 185}}, {{1, 19}, {28, 49}, {157, 203}}};

and each of the sub-arrays above represents a range. No two sub-arrays in a given row has any overlap.

I want to check if given i of r[[i]] and a scalar x, I want to check if any of the sub-arrays have x within their range.

e.g. if i =2 and x=175 is TRUE because {164,185} has it, but x=75 is FALSE since none of the {1, 5}, {25, 63}, {118, 132}, {164, 185} has it.

I do not want to use MapThread and use compilable functions, UnitStep if possible.

share|improve this question
    
I'm happy to be able to quickly answer this one for you. –  Mr.Wizard Aug 6 at 21:44
    
@Mr.Wizard Thank you. Look for more brain picking from me on SE. +1 –  brama Aug 6 at 21:50

4 Answers 4

up vote 4 down vote accepted

First convert your sub-arrays to Interval format:

r2 = Interval @@@ r;

Then you may use IntervalMemberQ:

i = 2;
x = 175;

IntervalMemberQ[r2[[i]], x]
True

It will be difficult to compile a complete function for your problem because the input will need to be a rectangular tensor, and your data is not:

TensorQ[r]
False

You could compile a function to check an individual sub-array but that is essentially what IntervalMemberQ already is I imagine. If you find this test to be the performance bottleneck in your code you should post the context in which you are using it (in a new question) so that other recommendations might be made.

share|improve this answer
    
Another gem!!...but is IntervalMemberQ compilable? –  brama Aug 6 at 22:04
    
@brama Why would it need to be compilable? It is already a fast System function. Are you creating code for export to another language, e.g. C? –  Mr.Wizard Aug 6 at 22:18
    
I was planning to use it in an already compiled code. Unfortunately, NoneTrue is not compilable. If I do not find any compilable functions to do it, I might still go with IntervalMemberQ and uncompilable function if it performs better than compilable with MapThread. –  brama Aug 6 at 23:24

Edit: If you have V10, then:

f[r_, i_, scalar_] := AnyTrue[r[[i]], #[[1]] <= scalar <= #[[2]] &]  

Otherwise,

f[r_, i_, scalar_] := ! VectorQ[r[[i]], Not[#[[1]] <= scalar <= #[[2]]] &]

Check:

f[r, 2, 175]

True

f[r, 2, 75]

False

share|improve this answer
    
Echo my comment to Algohi: it is highly inefficient to expand intervals to an explicit range of numbers. It also works only for integer x values, assuming a step size of 1. –  Mr.Wizard Aug 6 at 22:24
    
@Mr.Wizard. I agree. I was just working on a fix. –  RunnyKine Aug 6 at 22:25
    
@Mr.Wizard. See edit. –  RunnyKine Aug 6 at 22:49
    
Sorry to keep criticizing, but the problem with Or @@ is that you test every interval even if the first one is a match. This is why I used NoneTrue. +1 for making this a function however. –  Mr.Wizard Aug 6 at 23:11
    
@Mr.Wizard, your criticisms are appreciated and thanks. I'll keep working on it. –  RunnyKine Aug 6 at 23:27

How about this?

x = 175;
Map[MemberQ[#, x] &, Apply[Range, r, {2}], {2}]

(*{{False, False, False}, {False, False, False, True}, {False, False, 
  True}}*)
share|improve this answer
    
This is much less efficient than it could be as you expand each interval rather than merely comparing end points. See my updated answer for how one might approach this. –  Mr.Wizard Aug 6 at 22:23
Pick[r, ! Cases[#, {x_, y_} /; x <= 175 <= y] == {} & /@ r]

If you just want to check if the number belongs to any interval in a row of r:

!Cases[#,{x_,y_}/;x<=175<=y]=={}&/@r
(* {False,True,True} *)

!Cases[#,{x_,y_}/;x<=75<=y]=={}&/@r
(* {False,False,False} *)
share|improve this answer

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.