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.

Given that there is a set of points, for example, {{3,4,2},{5,2,-1}}. How do I go about selecting the point that has the lowest absolute x, y or z-coordinate from the list? In this case, the point selected should be {{5,2,-1}} as 1 is the lowest absolute value among all the points. Would the command Select[{{3,4,2}, {5,2,-1}}, ...] be good enough to perform such operation? Specifically, my understanding is that Select[{{3,4,2}, {5,2,-1}}, ...] is useful for selecting each individual point that satisfies certain condition stated in the command, so the question is whether it would be possible to compare 2 different points to select the desired point under the Select[...] operation. Or would there be a better alternative to getting the desired point?

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

Since Min returns the smallest element of any of the lists, you can use Position:

list = RandomReal[1, {50, 3}];
list[[Position[list, Min[Abs@list]][[1, 1]]]]
share|improve this answer
1  
I guess you will need an extra Abs before the Mean. –  PlatoManiac Nov 8 '12 at 18:48
    
Ah yes, I missed the lowest absolute part –  David Slater Nov 8 '12 at 18:51
    
I'd use Pick[] for the purpose myself... –  J. M. Nov 8 '12 at 23:21
add comment

Select only looks at each element in the list to decide if it stays or it doesn't, much like Cases. Some options

f1 = Extract[#, (First@Position[Flatten@Abs@#, Min@Abs@#] + 2)~Quotient~3] &;
f2 = Extract[#, Ordering[#, 1, Min@Abs@#1 < Min@Abs@#2 &]] &;
f3 = First@SortBy[#, Min@Abs@# &] &;
f4 = First@Nearest[#, {0`, 0`, 0`}, DistanceFunction -> (Min@Abs[#2 - #1] &)] &;
f5 = Extract[#, Ordering[Min /@ Abs@#, 1]] &;
f6 = Extract[#, (Ordering[Abs@Flatten@#, 1] + 2)~Quotient~3] &;

So

f1[r] // AbsoluteTiming
f2[r] // AbsoluteTiming
f3[r] // AbsoluteTiming
f4[r] // AbsoluteTiming
f5[r] // AbsoluteTiming
f6[r] // AbsoluteTiming

gives

{0.1760238, {-12.1516, 56.6547, -0.000243945}}

{0.8061080, {-12.1516, 56.6547, -0.000243945}}

{0.0430082, {-12.1516, 56.6547, -0.000243945}}

{1.1661187, {-12.1516, 56.6547, -0.000243945}}

{0.0150015, {-12.1516, 56.6547, -0.000243945}}

{0.0060008, {-12.1516, 56.6547, -0.000243945}}

share|improve this answer
    
Interesting comparisons. For your last one, f6, I got an additional speed boost by omitting the unused coordinates from the argument of Ordering: f7=Extract[#1,Ordering[Abs[#1[[All,1]]],1]]&. –  Jens Nov 9 '12 at 6:04
    
@Jens, I understood he wanted the minimum abs of any of the three coordinates, your suggested code would only look at the first one, right? –  Rojo Nov 9 '12 at 13:22
    
Oh, right. I'm solving a different problem - If I do my approach for each component separately, I think your f6 wins the speed comparison again. –  Jens Nov 9 '12 at 16:11
add comment

There's a little function I call MinBy I like to use from time to time (see here). It relates to Min the same way SortBy relates to Sort.

MinBy[list_, fun_] := list[[First@Ordering[fun /@ list, 1]]]

This function gives yet another simple solution to your question:

points = {{3, 4, 2}, {5, 2, -1}}
MinBy[points, Composition[Min, Abs]]

Note that an inherent problem with using MinBy is that is always returns only a single result, even if there are several equivalent elements of the list that could be considered minimal. This solution will always return only a single point.

share|improve this answer
add comment

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.