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$ – aardvark2012 Oct 4 '17 at 10:09
  • $\begingroup$ I used Flatten and DeleteCases justto get rid of some brackets. Now I try your suggestion. Thanks $\endgroup$ – daniele cozzolino Oct 4 '17 at 11:57
  • $\begingroup$ Unfortunately, same result. $\endgroup$ – daniele cozzolino Oct 4 '17 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$ – aardvark2012 Oct 4 '17 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$ – daniele cozzolino Oct 4 '17 at 12:20
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$ – daniele cozzolino Oct 4 '17 at 12:58
  • $\begingroup$ They work fine. Thank you. $\endgroup$ – daniele cozzolino Oct 4 '17 at 14:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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