File: realrandom.gi

package info (click to toggle)
gap-io 4.4.6%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 740 kB
  • ctags: 106
  • sloc: xml: 2,857; ansic: 2,823; sh: 38; makefile: 35
file content (119 lines) | stat: -rw-r--r-- 3,950 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#############################################################################
##
##  realrandom.gi           IO package
##                                                        by Max Neunhoeffer
##
##  Copyright (C) 2006-2010 by Max Neunhoeffer
##  This file is free software, see license information at the end.
##
##  Code for "real" random sources using /dev/random
##
#############################################################################

InstallMethod( Init, "for a real random source",
  [IsRealRandomSource,IsString], 1,
  function( r, type )
    local f;
    if type <> "random" and type <> "urandom" then
        Error("seed must be \"random\" or \"urandom\"");
    fi;
    if type = "random" then
        f := IO_File("/dev/random",128);  # Use smaller buffer size
    else
        f := IO_File("/dev/urandom",1024);  # Use medium buffer size
    fi;
    if f = fail then return fail; fi;
    r!.file := f;
    r!.type := type;
    return r;
  end );

InstallMethod( State, "for a real random source",
  [IsRealRandomSource],
  function(r)
    return fail;
  end );

InstallMethod( Reset, "for a real random source",
  [IsRealRandomSource],
  function(r)
    return;
  end );

InstallMethod( Reset, "for a real random source and an object",
  [IsRealRandomSource,IsObject],
  function(r,o)
    return;
  end );

InstallMethod( Random, "for a real random source and two integers",
  [ IsRealRandomSource, IsInt, IsInt ],
  function( r, f, t )
    local c,d,h,i,l,q,s;
    d := t-f;   # we need d+1 different outcomes from [0..d]
    if d <= 0 then return fail; fi;
    l := (Log2Int(d)+1);      # now 2^l >= d
    l := (l+7) - (l+7) mod 8; # this rounds up to a multiple of 8, still 2^l>=d
    q := QuoInt(2^l,d+1);     # now q*(d+1) <= 2^l < (q+1)*(d+1)
                              # thus for 0 <= x   < 2^l
                              # we have  0 <= x/q <= d+1 <= 2^l/q
                              # Thus if we do QuoInt(x,q) we get something
                              # between 0 and d inclusively, and if x is
                              # evenly distributed in [0..2^l-1], all values
                              # between 0 and d occur equally often
    repeat
        s := IO_ReadBlock(r!.file,l/8); # note that l is divisible by 8
        h := "";
        for c in s do Append(h,HexStringInt(INT_CHAR(c))); od;
        i := IntHexString(h);  # this is now between 0 and 2^l-1 inclusively
        i := QuoInt(i,q);
    until i <= d;
    return f+i;
  end );

InstallMethod( Random, "for a real random source and a list",
  [ IsRealRandomSource, IsList ],
  function( r, l )
    local nr;
    repeat
        nr := Random(r,1,Length(l));
    until IsBound(l[nr]);
    return l[nr];
  end );

InstallMethod( ViewObj, "for a real random source",
  [IsRealRandomSource],
  function(rs)
    Print("<a real random source>");
  end );

InstallMethod( IO_Pickle, "for a real random source",
  [IsFile, IsRealRandomSource],
  function(f,rs)
    if IO_Write(f,"RSRE") = fail then return IO_Error; fi;
    if IO_Pickle(f,rs!.type) = IO_Error then return IO_Error; fi;
    return IO_OK;
  end );

IO_Unpicklers.RSRE := function(f)
  local t;
  t := IO_Unpickle(f);
  if t = IO_Error then return IO_Error; fi;
  return RandomSource(IsRealRandomSource,t);
end;


##
##  This program is free software: you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation, either version 3 of the License, or
##  (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License
##  along with this program.  If not, see <http://www.gnu.org/licenses/>.
##