8
$\begingroup$

Let's create a random list

n = 100;
data = Table[{RandomReal[{0, 2}], RandomReal[{-1, 1}]}, {i, 0, n}]

Now we divide the $(x,y)$ plane into four sectors with the center at (1,0)

ang1 = 45;
ang2 = 135;
m1 = Tan[ang1*Degree];
m2 = Tan[ang2 *Degree];
y1 = m1*(x - 1);
y2 = m2*(x - 1);
ls = Plot[{y1, y2}, {x, -2, 2}, 
    PlotStyle -> {{Magenta, Dashed, Thick}}, AspectRatio -> 1]

My question is how to count how many random points is at every sector.

Many thanks in advance.

$\endgroup$
8
$\begingroup$
n = 100;
data = Table[{RandomReal[{0, 2}], RandomReal[{-1, 1}]}, {i, 0, n}];

y1[x_] = x - 1;
y2[x_] = 1 - x;

Plot[{y1[x], y2[x]}, {x, -0.5, 2.5}, Epilog -> Point[data]]

enter image description here

selection = 
 Select[data, #[[2]] > y1[#[[1]]] && #[[2]] > y2[#[[1]]] &];


Plot[{y1[x], y2[x]}, {x, -0.5, 2.5}, Epilog -> Point[selection]]

enter image description here

Length[selection]

30

this code works for selection in all 4 sectors

s = Table[
Select[data, #[[2]]~op1~y1[#[[1]]] && #[[2]]~op2~y2[#[[1]]] &], 
{op1, {Greater, Less}}, {op2, {Greater, Less}}] // Flatten[#, 1] &;

Length /@ s

{27, 25, 25, 24}

$\endgroup$
  • $\begingroup$ What about the criteria of the other three sectors? $\endgroup$ – Vaggelis_Z Apr 4 '15 at 12:08
  • $\begingroup$ @Vaggelis_Z done $\endgroup$ – k_v Apr 4 '15 at 12:26
7
$\begingroup$
data2 = GatherBy[data, Sign @ {#[[2]] - m1 (#[[1]] - 1), #[[2]] - m2 (#[[1]] - 1)} &];

Length /@ data2
(* {29, 20, 24, 28} *)

ListPlot[data2, AspectRatio -> 1, Epilog -> ls[[1]], BaseStyle -> PointSize[Large]]

enter image description here

To get just the counts, you can also use Count with Sign:

Count[Sign[{#2 - m1 (# - 1), #2 - m2 (# - 1)}] & @@@ data, #] & /@ Tuples[{1, -1}, 2] 
(* {24, 20, 29, 28} *)

Count[Sign[{#2 - y1 /. x -> #, #2 - y2 /. x -> #}] & @@@ data, #] & /@
  Tuples[{1, -1}, 2]
(* {24, 20, 29, 28} *)

{Row@{#}, 
    Count[Sign[{#2 - m1 (# - 1), #2 - m2 (# - 1)}] & @@@ data, #]} & /@
   Tuples[{1, -1}, 2] // 
 TableForm[#, TableHeadings -> {None, {"Signs", "Count"}}] &

enter image description here

or, with UnitStep:

Count[UnitStep[{#2 - m1 (# - 1), #2 - m2 (# - 1)}] & @@@ data, #]& /@Tuples[{1, 0}, 2] 
(* {24, 20, 29, 28} *)

Count[UnitStep[{#2 - y1 /. x -> #, #2 - y2 /. x -> #}] & @@@ data, #] & /@
  Tuples[{1, 0}, 2] 
(* {24, 20, 29, 28} *)
$\endgroup$
2
$\begingroup$

You can refine your list of data usind Cases

s1 = Cases[data, l_List /;
     (l[[1]] > 1) &&
      (l[[2]] > m2*(l[[1]] - 1)) &&
      (l[[2]] < m1*(l[[1]] - 1))
     ];

There are conditional pattern l_List which will be applied for elements of your data list. As result, you obtain following:

Show[
ListPlot@data,
ListPlot[s1, PlotStyle -> Red],
Plot[{y1, y2}, {x, -2, 2}, PlotStyle -> {{Magenta, Dashed, Thick}}, 
AspectRatio -> 1]] 

enter image description here

$\endgroup$
2
$\begingroup$

kglr's method can be greatly enhanced by using vectorization and Tally or Counts.

SeedRandom[0]
n = 1*^6;
data = {RandomReal[{0, 2}, n], RandomReal[{-1, 1}, n]}\[Transpose];

{m1, m2} = {1, -1};

(* kglr's code *)
Count[Sign[{#2 - m1 (# - 1), #2 - m2 (# - 1)}] & @@@ data, #] & /@ 
  Tuples[{1, -1}, 2] // RepeatedTiming

(* my refactoring *)
Sign[{#2 - m1 (# - 1), #2 - m2 (# - 1)}]\[Transpose] & @@ (data\[Transpose]) // 
  Counts // RepeatedTiming
{12.91, {249666, 249914, 250638, 249782}}

{0.333, <|{-1, 1} -> 250638, {1, 1} -> 249666,
          {-1, -1} -> 249782, {1, -1} -> 249914|>}

The output of Counts is an Association which if desired can be used like:

<|{-1, 1} -> 250638, {1, 1} -> 249666, {-1, -1} -> 249782, {1, -1} -> 249914|> /@ 
 Tuples[{1, -1}, 2]
{249666, 249914, 250638, 249782}
$\endgroup$

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.