Mathematica Programming Tips & Tricks Collection,                                                             Biomedical Imaging, TU/e

Subject of the Trick

Fast Max and Min Position

Author

Markus van Almsick

Keywords (List of Strings)

{"Fast", "Max", "Min", "Position", "Ordering"}

Abstract

The Mathematica command Ordering can find the position of a maximum or minimum in an n-dimensional data array faster than using Max or Min in Position.

Implementation

Code

PartitionInteger[pos_Integer, dims_List] := Mod[Reverse[FoldList[Quotient, pos - 1, Reverse[Rest[dims]]] ], dims] + 1

FastMaxPosition[data_List] := Ordering[Flatten[data], -1]/; TensorRank[data] === 1

FastMinPosition[data_List] := Ordering[Flatten[data], 1]/; TensorRank[data] === 1

FastMaxPosition[data_List] := PartitionInteger[#, Dimensions[data]] & @@ Ordering[Flatten[data], -1]

FastMinPosition[data_List] := PartitionInteger[#, Dimensions[data]] & @@ Ordering[Flatten[data], 1]

Explanation (Optional)

Up front we install the utility function PartitionInteger that converts the position pos in a flattened  array back to the coordinates in the nested array with the dimensions dims. Example:

PartitionInteger[14, {2, 4, 3}]

{2, 1, 2}

Flatten[Array[a, {2, 4, 3}]][[14]]

a[2, 1, 2]

Ordering[data,1] renders the position of the first element in the sorted data list, hence the position of a or the minimum. Ordering[data,-1] returns the position of the last element in the sorted data list, which is a or the maximum. To extend this command to n-dimensional arrays, we simply flatten these arrays and recalculate the coordinates from the linear position.

Example

Creating an array of random numbers between 0 and 1.

data = Table[Random[], {100}, {110}, {90}] ;

Inserting a maximum.

RowBox[{RowBox[{data[[45, 98, 7]],  , =,  , 1.1}], ;}]

Testing our implementation.

FastMaxPosition[data]

{45, 98, 7}

Comparing the result with a more conventional code.

Position[data, Max[data], {TensorRank[data]}, 1]

{{45, 98, 7}}

Comparing the execution speed:

Timing[Do[FastMaxPosition[data], {100}] ;]

RowBox[{{, RowBox[{RowBox[{3.25,  , Second}], ,, Null}], }}]

Timing[Do[Position[data, Max[data], {TensorRank[data]}, 1], {100}] ;]

RowBox[{{, RowBox[{RowBox[{81.43,  , Second}], ,, Null}], }}]

Note the speed gain by a factor of 25!


Created by Mathematica  (October 24, 2003)