2
$\begingroup$

I am trying to do:

Select[minimus[[6]], #1[[2]] < (min[[6]] + emin[[6]]) &]

applied to all elements of minimus, min and emin. They all have the same Length, but minimus is a list of pair coordinates {{x1, y1}, {x2, y2}, ..., {xN, yN}} while both min and emin are lists of values.

I thought something like this would work:

Map[Select[minimus[[#2]], #1[[2]] < (min[[#2]] + emin[[#2]])&]&, Range[Length[minimus]]]

But it didn't...

Any thoughts?

$\endgroup$
  • 1
    $\begingroup$ Perhaps you can include a sample list with the expected output? $\endgroup$ – march Apr 19 '16 at 16:30
  • $\begingroup$ Anyway, maybe something like Function[{x}, Select[minimus[[x]], #1[[2]] < (min[[x]] + emin[[x]]) &] & /@ Range@Length@minimus. Or just Table[Select[minimus[[x]], #1[[2]] < (min[[x]] + emin[[x]]) &], {x, Length@minimus}]. $\endgroup$ – march Apr 19 '16 at 16:32
  • $\begingroup$ Select[minimus[[6]]... is selecting from two values, you sure ties is correct? See my answer if you need another thing. $\endgroup$ – BlacKow Apr 19 '16 at 16:43
7
$\begingroup$
Pick[minimus, UnitStep[min + emin - minimus[[;; , 2]]], 1]

or a pure function that does the same thing:

pF = Pick[#, UnitStep[#2 + #3 - #[[;; , 2]]], 1] &;

Examples:

min = RandomReal[{0, 0.5}, 10^6];
emin = RandomReal[{0, 0.5}, 10^6];
minimus = RandomReal[{0, 1}, {10^6, 2}];

p1 = pF[minimus, min, emin]; // AbsoluteTiming // First

0.059911

p2 = Pick[minimus, Thread[minimus[[;; , 2]] < (min + emin)]]; // 
  AbsoluteTiming // First

0.988790

p3 = First@Transpose@Select[Transpose@{minimus, min, emin}, 
     #[[1, 2]] < (#[[2]] + #[[3]]) &]; // AbsoluteTiming // First

2.497177

p1 == p2 == p3

True

Update: A variation suggested by @ciao in the comments is faster for large lists:

pFx = With[{tot = #2 + #3}, Pick[#, UnitStep[Subtract[tot, Transpose[#][[2]]]], 1]] &;

min = RandomReal[{0, 0.5}, 10^7];
emin = RandomReal[{0, 0.5}, 10^7];
minimus = RandomReal[{0, 1}, {10^7, 2}];

p1 = pF[minimus, min, emin]; // AbsoluteTiming // First

0.555083

p1x = pFx[minimus, min, emin]; // AbsoluteTiming // First

0.461842

p1x == p1

True

$\endgroup$
  • $\begingroup$ Amazing... I'm awesome to give the slowest solution! $\endgroup$ – BlacKow Apr 19 '16 at 17:24
  • $\begingroup$ We've both been schooled! $\endgroup$ – Quantum_Oli Apr 19 '16 at 17:32
  • $\begingroup$ @BlacKow and Quantum_Oli, thank you both for the votes. $\endgroup$ – kglr Apr 19 '16 at 17:54
  • 2
    $\begingroup$ I think you might find this a bit faster, particularly on large lists (at least it is on my machine): pFx=With[{tot = #2+ #3}, Pick[#, UnitStep[Subtract[tot, Transpose[#][[2]]]], 1]] &; - oh, and +1 o/c $\endgroup$ – ciao Apr 20 '16 at 0:53
  • $\begingroup$ @ciao, thank you so much. It is faster on my machine too. $\endgroup$ – kglr Apr 20 '16 at 1:13
4
$\begingroup$

Another approach, using Pick:

min = RandomReal[{0, 0.5}, 10]
emin = RandomReal[{0, 0.5}, 10]
minimus = RandomReal[{0, 1}, {10, 2}]

Pick[minimus, Thread[minimus[[;; , 2]] < (min + emin)]]
$\endgroup$
  • $\begingroup$ +1 Your approach is about twice faster than mine... $\endgroup$ – BlacKow Apr 19 '16 at 16:49
3
$\begingroup$

Assuming that you want to select all values from minimus such as its second element is less than sum of corresponding min and emin

RandomSeed[3141592];
minimus = RandomReal[{0, 1}, {10, 2}];
min = RandomReal[{0, 1}, 10];
emin = RandomReal[{0, 1}, 10];
First@Transpose@
  Select[Transpose@{minimus, min, 
     emin}, #[[1, 2]] < (#[[2]] + #[[3]]) &]
$\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.