Skip to content

Commit

Permalink
Add PositionMaximum and PositionMinimum
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisJefferson committed Nov 22, 2016
1 parent 7183c69 commit 7e57162
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/ref/lists.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1416,6 +1416,7 @@ The latter can be done also using <Ref Func="ListWithIdenticalEntries"/>.
<#Include Label="PositionNthOccurrence">
<#Include Label="PositionSorted">
<#Include Label="PositionSet">
<#Include Label="PositionMaximum">
<#Include Label="PositionProperty">
<#Include Label="PositionsProperty">
<#Include Label="PositionBound">
Expand Down
40 changes: 40 additions & 0 deletions lib/list.gd
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,44 @@ DeclareGlobalFunction( "PositionSet" );
DeclareOperation( "PositionProperty", [ IsList, IsFunction ] );
DeclareOperation( "PositionProperty", [ IsList, IsFunction, IS_INT ] );

#############################################################################
##
#O PositionMaximum( <list> [, <func>] )
#O PositionMinimum( <list> [, <func>] )
##
## <#GAPDoc Label="PositionMaximum">
## <ManSection>
## <Func Name="PositionMaximum" Arg='list [, func]'/>
## <Func Name="PositionMinimum" Arg='list [, func]'/>
##
## <Description>
## returns the position of maximum (with <Ref Func="PositionMaximum"/>) or
## minimum (with <Ref Func="PositionMinimum"/>) entry in the list <A>list</A>.
## If a second argument <A>func</A> is passed, then return instead the position
## of the largest/smallest entry in <C>List( <A>list</A> , <A>func</A> )</C>.
## If several entries of the list are equal
## to the maximum/minimum, the first such position is returned.
## <P/>
## <Example><![CDATA[
## gap> PositionMaximum( [2,4,-6,2,4] );
## 2
## gap> PositionMaximum( [2,4,-6,2,4], x -> -x);
## 3
## gap> PositionMinimum( [2,4,-6,2,4] );
## 3
## gap> PositionMinimum( [2,4,-6,2,4], x -> -x);
## 2
## ]]></Example>
## <P/>
## <Ref Func="Maximum" Label="for various objects"/> and
## <Ref Func="Minimum" Label="for various objects"/>
## allow you to find the maximum or minimum element of a list directly.
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareGlobalFunction( "PositionMaximum" );
DeclareGlobalFunction( "PositionMinimum" );

#############################################################################
##
Expand Down Expand Up @@ -1717,6 +1755,7 @@ DeclareOperation( "StableSortParallel",
## gap> Maximum( [1,2], [0,15], [1,5], [2,-11] );
## [ 2, -11 ]
## ]]></Example>
## To get the index of the maximum element use <Ref Func="PositionMaximum"/>
## </Description>
## </ManSection>
## <#/GAPDoc>
Expand Down Expand Up @@ -1759,6 +1798,7 @@ DeclareGlobalFunction( "Maximum" );
## gap> Minimum( [ 1, 2 ], [ 0, 15 ], [ 1, 5 ], [ 2, -11 ] );
## [ 0, 15 ]
## ]]></Example>
## To get the index of the minimum element use <Ref Func="PositionMinimum"/>
## </Description>
## </ManSection>
## <#/GAPDoc>
Expand Down
68 changes: 68 additions & 0 deletions lib/list.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,74 @@ InstallMethod( PositionProperty,
end );


#############################################################################
##
#M PositionMaximum(<list>[, <func>]) . position of the largest element
#M PositionMinimum(<list>[, <func>]) . position of the smallest element
##

InstallGlobalFunction( PositionMaximum,
function ( args... )
local list, func, i, bestval, bestindex, ival;

if Length(args) < 1 or Length(args) > 2
or not(IsList(args[1]))
or (Length(args) = 2 and not(IsFunction(args[2]))) then
ErrorNoReturn("Usage: PositionMaximum(<list>, [<func>])");
fi;

list := args[1];
if Length(args) = 2 then
func := args[2];
else
func := IdFunc;
fi;

bestindex := fail;
for i in [ 1 .. Length( list ) ] do
if IsBound( list[i] ) then
ival := func ( list[ i ] );

if not( IsBound(bestval) ) or ival > bestval then
bestval := ival;
bestindex := i;
fi;
fi;
od;
return bestindex;
end );

InstallGlobalFunction( PositionMinimum,
function ( args... )
local list, func, i, bestval, bestindex, ival;

if Length(args) < 1 or Length(args) > 2
or not(IsList(args[1]))
or (Length(args) = 2 and not(IsFunction(args[2]))) then
ErrorNoReturn("Usage: PositionMinimum(<list>, [<func>])");
fi;

list := args[1];
if Length(args) = 2 then
func := args[2];
else
func := IdFunc;
fi;

bestindex := fail;
for i in [ 1 .. Length( list ) ] do
if IsBound( list[i] ) then
ival := func ( list[ i ] );

if not( IsBound(bestval) ) or ival < bestval then
bestval := ival;
bestindex := i;
fi;
fi;
od;
return bestindex;
end );

#############################################################################
##
#M PositionsProperty(<list>,<func>) . positions of elements with a property
Expand Down
36 changes: 36 additions & 0 deletions tst/testinstall/listgen.tst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,42 @@ gap> MinimumList( [ 1, 2 .. 20 ] );
1
gap> MinimumList( [ 10, 8 .. 2 ] );
2
gap> PositionMaximum([2,4,6,4,2,6]);
3
gap> PositionMaximum([2,4,6,4,2,6], x -> -x);
1
gap> PositionMinimum([2,4,6,4,2,6]);
1
gap> PositionMinimum([2,4,6,4,2,6], x -> -x);
3
gap> PositionMaximum();
Error, Usage: PositionMaximum(<list>, [<func>])
gap> PositionMaximum(2);
Error, Usage: PositionMaximum(<list>, [<func>])
gap> PositionMaximum([1,2], 2);
Error, Usage: PositionMaximum(<list>, [<func>])
gap> PositionMaximum([1,2], x -> x, 2);
Error, Usage: PositionMaximum(<list>, [<func>])
gap> PositionMinimum();
Error, Usage: PositionMinimum(<list>, [<func>])
gap> PositionMinimum([1,2], 2);
Error, Usage: PositionMinimum(<list>, [<func>])
gap> PositionMinimum(2);
Error, Usage: PositionMinimum(<list>, [<func>])
gap> PositionMinimum([1,2], x -> x, 2);
Error, Usage: PositionMinimum(<list>, [<func>])
gap> PositionMaximum([]);
fail
gap> PositionMaximum([,,,]);
fail
gap> PositionMaximum([2,,4,,6]);
5
gap> PositionMinimum([2,,4,,6]);
1
gap> PositionMinimum([,,,]);
fail
gap> PositionMinimum([]);
fail
gap> String( l );
"[ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]"
gap> String( [ 1 .. 10 ] );
Expand Down

0 comments on commit 7e57162

Please sign in to comment.