source: git/factory/cf_random.cc

spielwiese
Last change on this file was f8d27e1, checked in by Max Horn <max@…>, 4 years ago
Move FLINTrandom into factory to fix test suite crashes Without this, `make check` runs into segfaults in tests that use factory but not the full Singular library, as factory accesses FLINTrandom but does not contain its definition.
  • Property mode set to 100644
File size: 3.5 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2
3
4#include "config.h"
5
6
7#include <time.h>
8
9#include "cf_assert.h"
10
11#include "cf_defs.h"
12#include "cf_random.h"
13#include "ffops.h"
14#include "gfops.h"
15#include "imm.h"
16
17#ifdef HAVE_FLINT
18extern "C"
19{
20#ifndef __GMP_BITS_PER_MP_LIMB
21#define __GMP_BITS_PER_MP_LIMB GMP_LIMB_BITS
22#endif
23#include <flint/flint.h>
24
25GLOBAL_VAR flint_rand_t FLINTrandom;
26}
27#endif
28
29class RandomGenerator {
30private:
31    const int ia, im, iq, ir, deflt;
32    int s;
33
34    // s must not equal zero!
35    void seedInit( int ss ) { s = ((ss == 0) ? deflt : ss); }
36public:
37    RandomGenerator();
38    RandomGenerator( int ss );
39    ~RandomGenerator() {}
40    int generate();
41    void seed( int ss ) { seedInit( ss ); }
42};
43
44RandomGenerator::RandomGenerator() : ia(16807), im(2147483647), iq(127773), ir(2836), deflt(123459876)
45{
46  seedInit( (int)time( 0 ) );
47}
48
49RandomGenerator::RandomGenerator( int ss ) : ia(16807), im(2147483647), iq(127773), ir(2836), deflt(123459876)
50{
51  seedInit( ss );
52}
53
54int
55RandomGenerator::generate()
56{
57    int k;
58
59    k = s/iq;
60    s = ia*(s-k*iq)-ir*k;
61    if ( s < 0 ) s += im;
62
63    return s;
64}
65
66INST_VAR RandomGenerator ranGen;
67
68CanonicalForm FFRandom::generate () const
69{
70    return CanonicalForm( int2imm_p( factoryrandom( ff_prime ) ) );
71}
72
73CFRandom * FFRandom::clone () const
74{
75    return new FFRandom();
76}
77
78CanonicalForm GFRandom::generate () const
79{
80    int i= factoryrandom( gf_q );
81    if ( i == gf_q1 ) i++;
82    return CanonicalForm( int2imm_gf( i ) );
83}
84
85CFRandom * GFRandom::clone () const
86{
87    return new GFRandom();
88}
89
90
91IntRandom::IntRandom()
92{
93    max = 50;
94}
95
96IntRandom::IntRandom( int m )
97{
98    max = m;
99}
100
101IntRandom::~IntRandom() {}
102
103CanonicalForm IntRandom::generate() const
104{
105    return factoryrandom( 2*max )-max;
106}
107
108CFRandom * IntRandom::clone() const
109{
110    return new IntRandom( max );
111}
112
113AlgExtRandomF::AlgExtRandomF()
114{
115    ASSERT( 0, "not a valid random generator" );
116}
117
118AlgExtRandomF::AlgExtRandomF( const AlgExtRandomF & )
119{
120    ASSERT( 0, "not a valid random generator" );
121}
122
123AlgExtRandomF& AlgExtRandomF::operator= ( const AlgExtRandomF & )
124{
125    ASSERT( 0, "not a valid random generator" );
126    return *this;
127}
128
129AlgExtRandomF::AlgExtRandomF( const Variable & v )
130{
131    ASSERT( v.level() < 0, "not an algebraic extension" );
132    algext = v;
133    n = degree( getMipo( v ) );
134    gen = CFRandomFactory::generate();
135}
136
137AlgExtRandomF::AlgExtRandomF( const Variable & v1, const Variable & v2 )
138{
139    ASSERT( v1.level() < 0 && v2.level() < 0 && v1 != v2, "not an algebraic extension" );
140    algext = v2;
141    n = degree( getMipo( v2 ) );
142    gen = new AlgExtRandomF( v1 );
143}
144
145AlgExtRandomF::AlgExtRandomF( const Variable & v, CFRandom * g, int nn )
146{
147    algext = v;
148    n = nn;
149    gen = g;
150}
151
152AlgExtRandomF::~AlgExtRandomF()
153{
154    delete gen;
155}
156
157CanonicalForm AlgExtRandomF::generate() const
158{
159    CanonicalForm result;
160    for ( int i = 0; i < n; i++ )
161      result += power( algext, i ) * gen->generate();
162    return result;
163}
164
165CFRandom * AlgExtRandomF::clone () const
166{
167    return new AlgExtRandomF( algext, gen->clone(), n );
168}
169
170CFRandom * CFRandomFactory::generate()
171{
172    if ( getCharacteristic() == 0 )
173        return new IntRandom();
174    if ( getGFDegree() > 1 )
175        return new GFRandom();
176    else
177        return new FFRandom();
178}
179
180int factoryrandom( int n )
181{
182    if ( n == 0 )
183        return (int)ranGen.generate();
184    else
185        return ranGen.generate() % n;
186}
187
188
189void factoryseed ( int s )
190{
191    ranGen.seed( s );
192
193#ifdef HAVE_FLINT
194    flint_randinit(FLINTrandom);
195#endif
196}
Note: See TracBrowser for help on using the repository browser.