3
$\begingroup$

I am new in this community so forgive me if this is a sort of re-post. I am trying to convert this MATLAB script:

v_i = find(rect_xmin <= Xv & Xv <= rect_xmax & rect_ymin <= Yv & Yv <= rect_ymax)

in Mathematica. What it does (or at least it seems so to me) is to find the element positions in the two column vectors, Xv and Yv, satisfying the specified criteria. What I did so far is this:

 intx = DeleteCases[
  Flatten[Position[Xv, _?(xrectmin <= # <= xrectmax &)]], 1]; 
inty = 
 DeleteCases[Flatten[Position[Yv, _?( yrectmin <= # <= yrectmax &)]], 
  1];

pointpos = Intersection[intx, inty];

But it results in a vector of 800 elements, while there should be 400. Could you help me to understand what is wrong? Thank you!

$\endgroup$
6
  • $\begingroup$ Have you tried Position[xv, x_ /; xrectmin <= x <= xrectmax], and similarly for yv? I'm not really clear on what the Flatten and DeleteCases are for... $\endgroup$ Oct 4, 2017 at 10:09
  • $\begingroup$ I used Flatten and DeleteCases justto get rid of some brackets. Now I try your suggestion. Thanks $\endgroup$ Oct 4, 2017 at 11:57
  • $\begingroup$ Unfortunately, same result. $\endgroup$ Oct 4, 2017 at 12:05
  • $\begingroup$ Then you really need to post more details (like: what are Xv Yv, xrectmin and yrectmin; what output precisely are you looking for) because that code will give you the positions of the elements that satisfy the conditions. If that's not what you want, please be clear what you do want. $\endgroup$ Oct 4, 2017 at 12:15
  • $\begingroup$ Basically, I want to translate that Matlab script (the first one) into a Mathematica script. What that script does is to find the position of the elements that satisfy the 4 conditions all together. Xv and Yv are column vectors containing a lot of numbers, let´s say from -100 to 100. xrectmin, xrectmax, as well as yrectmin, yrectmax set the limit for those conditions. For instance, (-10,10) for x and (-40,40) for y. I hope is clear :/ $\endgroup$ Oct 4, 2017 at 12:20

1 Answer 1

5
$\begingroup$

Let's make some sample data:

xmin = 0.; ymin = 0.;
xmax = 0.4; ymax = 0.3;

points = RandomReal[1, {100, 2}];

With pattern matching

This is a classical and straightforward way using pattern matching. It is very Mathematica-like:

Position[points, {x_, y_} /; xmin <= x <= xmax && ymin <= y <= ymax]
(* {{5}, {28}, {39}, {44}, {52}, {54}, {55}, {58}, {63}, {72}, {75}} *)

Timing with 5 million points: 7.01 s.

With regions

reg = Rectangle[{xmin, ymin}, {xmax, ymax}];

memberFun = RegionMember[reg];

Position[memberFun[points], True]
(* {{5}, {28}, {39}, {44}, {52}, {54}, {55}, {58}, {63}, {72}, {75}} *)

Timing with 5 million points: 0.42 s.

With BoolEval

A MATLAB-ish way with my BoolEval package:

<< BoolEval`

{xcoord, ycoord} = Transpose[points];

SparseArray[
  BoolEval[xmin <= xcoord <= xmax && ymin <= ycoord <= ymax]
]["NonzeroPositions"]
(* {{5}, {28}, {39}, {44}, {52}, {54}, {55}, {58}, {63}, {72}, {75}} *)

Timing with 5 million points: 0.019 s.

$\endgroup$
2
  • $\begingroup$ This seems a very useful answer. Thank you! Just the time to test them and I´ll let you know. $\endgroup$ Oct 4, 2017 at 12:58
  • $\begingroup$ They work fine. Thank you. $\endgroup$ Oct 4, 2017 at 14:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.