gap
gap copied to clipboard
Missing random function
The function
gap> Random(GeneralLinearGroup(2, Integers));
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
Error, no 2nd choice method found for `Random' on 1 arguments at /home/mathieu/opt/gap-4.11.1/lib/methsel2.g:249 called from
<function "HANDLE_METHOD_NOT_FOUND">( <arguments> )
called from read-eval loop at *stdin*:16
type 'quit;' to quit to outer loop
Of course for permutation groups it works correctly and I believe returns random point with a probability distribution that is equidistributed over the group.
It is not possible to do equidistributed probability distribution over infinite discrete sets. But the thing is that GAP has a probability distribution over the integers, that is Random(Integers) so clearly equidistribution is not a requirement for having a Random function implemented for your type.
Thus for me something like
Random:=function(g)
local retVal, LGen, iter;
retVal := Identity(g)
LGen:=GeneratorsOfGroup(g);
for iter in [1..AbsInt(Random(Integers))]
do
retVal := retVal * Random(LGen);
od;
return retVal;
end;
Which would work fine for my use case except for one problem. The probability distribution returned by Random(Integers) is exagerately concentrated around 0. In fact running over 10 million entries gives
ListVal:=[];
for i in [1..10000000]
do
Add(ListVal, AbsInt(Random(Integers)));
od;
Collected(ListVal);
gives [ [ 0, 1760818 ], [ 1, 3203816 ], [ 2, 2404711 ], [ 3, 1477635 ], [ 4, 739234 ], [ 5, 295366 ], [ 6, 92540 ], [ 7, 21785 ], [ 8, 3691 ], [ 9, 379 ], [ 10, 25 ] ] which is too narrow a distribution.
But of course there is no random distribution that fits everyone needs. So, this could be a global parameter chose by the users in advance.
Let me know what you think.
As you point out, there is no equidistribution on the integers. Nor does Random(Integers) do anything clever or useful (and actually, I wish it did not exist at all, at least in this form). From its documentation:
Random for integers returns pseudo random integers between -10 and 10 distributed according to a binomial distribution. To generate uniformly distributed integers from a range, use the construction
Random( [ low .. high ] )(see Random (30.7-1)).
I don't think we should add more of these problematic Random methods. If at all, one would need a robust concept for specifying a distribution on the integers, which then can be passed to Random, and which then can be used to derive a distribution for use by a Random method for GL(n,Integers), and so on.
Note that there is a function RandomUnimodularMat(n) which you can use to generate "random" elements for GL(n,Integer) but it also doesn't let you specify a distribution, so... shrug
There is PseudoRandom, though for matrix groups over the integers this often produces entries with 100000s of digits. What I have been doing in such situations is to use PseudoRandom for a finitely presented group which allows to give a radius option, and then to evaluate this word in the matrix group generators.
I seem to remember that Random(Integers) always return a value in [-12, 12] or something similar,
exaggeratedly concentrated around 0
sounds about right :)