1497 lines
38 KiB
C++
1497 lines
38 KiB
C++
|
|
/*
|
||
|
|
----
|
||
|
|
This file is part of SECONDO.
|
||
|
|
|
||
|
|
Copyright (C) 2007, University in Hagen, Department of Computer Science,
|
||
|
|
Database Systems for New Applications.
|
||
|
|
|
||
|
|
SECONDO 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 2 of the License, or
|
||
|
|
(at your option) any later version.
|
||
|
|
|
||
|
|
SECONDO 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 SECONDO; if not, write to the Free Software
|
||
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
|
----
|
||
|
|
|
||
|
|
//paragraph [1] Title: [{\Large \bf ] [}]
|
||
|
|
//[->] [\ensuremath{\rightarrow}]
|
||
|
|
|
||
|
|
[1] Secondo GSLAlgebra
|
||
|
|
|
||
|
|
|
||
|
|
March 22, 2007 C. Duentgen created the algebra
|
||
|
|
|
||
|
|
\begin{center}
|
||
|
|
\footnotesize
|
||
|
|
\tableofcontents
|
||
|
|
\end{center}
|
||
|
|
|
||
|
|
|
||
|
|
1 Overview
|
||
|
|
|
||
|
|
This algebra provides functionality of the GSL (Gnu Scinetific Library) to the
|
||
|
|
Secondo user.
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
2 Includes
|
||
|
|
|
||
|
|
In addition to the normal CC includes we have to include header files
|
||
|
|
for QueryProcessor and Tuplemanager and the file which contains the
|
||
|
|
definitions of our four classes: ~CcInt~, ~CcReal~, ~CcBool~, ~CcString~.
|
||
|
|
and --- of cause --- the GSL.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "Algebra.h"
|
||
|
|
#include "NestedList.h"
|
||
|
|
#include "QueryProcessor.h"
|
||
|
|
#include "StandardTypes.h"
|
||
|
|
|
||
|
|
#include <iostream>
|
||
|
|
#include <string>
|
||
|
|
#include <sstream>
|
||
|
|
|
||
|
|
#include <cstdlib>
|
||
|
|
#include <unistd.h>
|
||
|
|
#include <errno.h>
|
||
|
|
|
||
|
|
#include <NList.h>
|
||
|
|
|
||
|
|
#ifndef SECONDO_WIN32
|
||
|
|
#define HAVE_INLINE
|
||
|
|
#endif
|
||
|
|
#include <gsl/gsl_rng.h>
|
||
|
|
#include <gsl/gsl_randist.h>
|
||
|
|
|
||
|
|
#include "GSLAlgebra.h"
|
||
|
|
|
||
|
|
/*
|
||
|
|
3. C++ Data Types
|
||
|
|
|
||
|
|
3.1 Type ~randomgen~
|
||
|
|
|
||
|
|
Type ~randomgen~ is a random number generator. As an object, it also stores
|
||
|
|
the type of generation method to apply, and a random seed.
|
||
|
|
|
||
|
|
It could be expanded to become of kind SIMPLE or DATA later. The ~defined~ flag
|
||
|
|
was included to this goal.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
// implementations for class GslRandomgen
|
||
|
|
GslRandomgen::GslRandomgen()
|
||
|
|
{} // the simple constructor. Never use this one!
|
||
|
|
|
||
|
|
GslRandomgen::GslRandomgen( const bool def )
|
||
|
|
: defined( def )
|
||
|
|
{ // the simple constructor
|
||
|
|
if( !initialized )
|
||
|
|
{
|
||
|
|
InitializeTables();
|
||
|
|
}
|
||
|
|
myType = gsl_rng_defaultIndex;
|
||
|
|
mySeed = gsl_rng_default_seed;
|
||
|
|
if( def )
|
||
|
|
{
|
||
|
|
me = gsl_rng_alloc(GetRngType(myType));
|
||
|
|
assert( me != NULL );
|
||
|
|
gsl_rng_set(me, mySeed);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
me = NULL;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
GslRandomgen::GslRandomgen( const int typeNo, const unsigned long seed )
|
||
|
|
: defined( true )
|
||
|
|
{ // the fully parameterized constructor
|
||
|
|
if( !initialized )
|
||
|
|
{
|
||
|
|
InitializeTables();
|
||
|
|
}
|
||
|
|
if(typeNo < 0 || typeNo >= gslalg_randomgeneratorTableSize)
|
||
|
|
{
|
||
|
|
defined = false;
|
||
|
|
me = NULL;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
myType = typeNo;
|
||
|
|
const gsl_rng_type *T = GetRngType(myType);
|
||
|
|
me = gsl_rng_alloc(T);
|
||
|
|
assert( me != NULL );
|
||
|
|
mySeed = seed;
|
||
|
|
gsl_rng_set(me, mySeed);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
GslRandomgen::GslRandomgen( const GslRandomgen& other )
|
||
|
|
{ // the copy constructor
|
||
|
|
defined = other.defined;
|
||
|
|
myType = other.myType;
|
||
|
|
mySeed = other.mySeed;
|
||
|
|
if( other.me != NULL )
|
||
|
|
me = gsl_rng_clone (other.me);
|
||
|
|
else
|
||
|
|
me = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
GslRandomgen& GslRandomgen::operator= ( const GslRandomgen& other )
|
||
|
|
{ // the assignment operator
|
||
|
|
defined = other.defined;
|
||
|
|
myType = other.myType;
|
||
|
|
mySeed = other.mySeed;
|
||
|
|
if( me != NULL )
|
||
|
|
{
|
||
|
|
gsl_rng_free(me);
|
||
|
|
me = NULL;
|
||
|
|
}
|
||
|
|
if( other.me != NULL )
|
||
|
|
{
|
||
|
|
me = gsl_rng_clone(other.me);
|
||
|
|
assert( me != NULL );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
me = NULL;
|
||
|
|
return *this;
|
||
|
|
}
|
||
|
|
|
||
|
|
GslRandomgen::~GslRandomgen()
|
||
|
|
{ // the destructor
|
||
|
|
if( me != NULL )
|
||
|
|
{
|
||
|
|
gsl_rng_free(me);
|
||
|
|
me = NULL;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
gsl_rng* GslRandomgen::GetGenerator()
|
||
|
|
{
|
||
|
|
return me;
|
||
|
|
}
|
||
|
|
|
||
|
|
inline void GslRandomgen::SetDefined( const bool def )
|
||
|
|
{ // set defined flag and ensure proper settings
|
||
|
|
if( def && !defined && me == NULL )
|
||
|
|
{ // create a valid instance for me*
|
||
|
|
myType = gsl_rng_defaultIndex;
|
||
|
|
gsl_rng_free(me);
|
||
|
|
me = gsl_rng_alloc(GetRngType(myType));
|
||
|
|
assert( me != NULL );
|
||
|
|
mySeed = gsl_rng_default_seed;
|
||
|
|
gsl_rng_set(me, mySeed);
|
||
|
|
}
|
||
|
|
defined = def;
|
||
|
|
}
|
||
|
|
|
||
|
|
inline bool GslRandomgen::IsDefined() const
|
||
|
|
{ // return defined flag
|
||
|
|
return defined;
|
||
|
|
}
|
||
|
|
|
||
|
|
inline size_t GslRandomgen::Sizeof() const
|
||
|
|
{ // return the size of used memory
|
||
|
|
return sizeof( *this ) + (me == NULL ? 0 : gsl_rng_size(me));
|
||
|
|
}
|
||
|
|
|
||
|
|
inline void GslRandomgen::SetSeed( const unsigned long seed )
|
||
|
|
{
|
||
|
|
assert( defined && me != NULL );
|
||
|
|
mySeed = seed;
|
||
|
|
gsl_rng_set (me, mySeed);
|
||
|
|
}
|
||
|
|
|
||
|
|
inline unsigned long GslRandomgen::GetSeed()
|
||
|
|
{
|
||
|
|
assert( defined && me != NULL );
|
||
|
|
return mySeed;
|
||
|
|
}
|
||
|
|
|
||
|
|
inline int GslRandomgen::GetType()
|
||
|
|
{
|
||
|
|
assert( defined && me != NULL );
|
||
|
|
return myType;
|
||
|
|
}
|
||
|
|
|
||
|
|
// inline unsigned long int GslRandomgen::NextInt()
|
||
|
|
unsigned long int GslRandomgen::NextInt()
|
||
|
|
{ // return next random int number from generator
|
||
|
|
// uniformly distributed [MinRand, MaxRand]
|
||
|
|
assert( defined && me != NULL );
|
||
|
|
return gsl_rng_get(me);
|
||
|
|
}
|
||
|
|
|
||
|
|
inline unsigned long int GslRandomgen::MinRand() const
|
||
|
|
{ // get minimum bounding value
|
||
|
|
assert( defined && me != NULL );
|
||
|
|
return gsl_rng_min(me);
|
||
|
|
}
|
||
|
|
|
||
|
|
inline unsigned long int GslRandomgen::MaxRand() const
|
||
|
|
{ // get maximum bounding value
|
||
|
|
assert( defined && me != NULL );
|
||
|
|
return gsl_rng_max(me);
|
||
|
|
}
|
||
|
|
|
||
|
|
double GslRandomgen::NextReal()
|
||
|
|
{ // returns a double precision floating point number
|
||
|
|
// uniformly distributed in the range [0,1)
|
||
|
|
assert( defined && me != NULL );
|
||
|
|
return gsl_rng_uniform(me);
|
||
|
|
}
|
||
|
|
|
||
|
|
inline double GslRandomgen::NextRealPos()
|
||
|
|
{ // returns a double precision floating point number
|
||
|
|
// uniformly distributed in the range (0,1)
|
||
|
|
assert( defined && me != NULL );
|
||
|
|
return gsl_rng_uniform_pos(me);
|
||
|
|
}
|
||
|
|
|
||
|
|
inline unsigned long int GslRandomgen::NextIntN(const unsigned long int n)
|
||
|
|
{ // returns a random integer from 0 to n-1
|
||
|
|
assert( defined && me != NULL && n >= 1 );
|
||
|
|
return gsl_rng_uniform_int (me, n);
|
||
|
|
}
|
||
|
|
|
||
|
|
void GslRandomgen::InitializeTables()
|
||
|
|
{ // initialize table of random number generators:
|
||
|
|
if( !GslRandomgen::initialized )
|
||
|
|
{
|
||
|
|
gsl_rng_env_setup(); // get default values
|
||
|
|
// get rng types
|
||
|
|
GslRandomgen::gslalg_randomgeneratorTable = gsl_rng_types_setup();
|
||
|
|
GslRandomgen::gslalg_randomgeneratorTableSize = 0;
|
||
|
|
GslRandomgen::gsl_rng_defaultIndex = 0;
|
||
|
|
while(GslRandomgen::gslalg_randomgeneratorTable[
|
||
|
|
GslRandomgen::gslalg_randomgeneratorTableSize] != NULL)
|
||
|
|
{
|
||
|
|
if( GslRandomgen::gslalg_randomgeneratorTable[
|
||
|
|
GslRandomgen::gslalg_randomgeneratorTableSize]->set
|
||
|
|
== gsl_rng_default->set )
|
||
|
|
{
|
||
|
|
GslRandomgen::gsl_rng_defaultIndex =
|
||
|
|
GslRandomgen::gslalg_randomgeneratorTableSize;
|
||
|
|
}
|
||
|
|
GslRandomgen::gslalg_randomgeneratorTableSize++;
|
||
|
|
}
|
||
|
|
GslRandomgen::initialized = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
const gsl_rng_type* GslRandomgen::GetRngType(int index)
|
||
|
|
{
|
||
|
|
assert( index >= 0 && index < gslalg_randomgeneratorTableSize );
|
||
|
|
return gslalg_randomgeneratorTable[index];
|
||
|
|
}
|
||
|
|
|
||
|
|
long GslRandomgen::rngType_getNoOfGenerators()
|
||
|
|
{
|
||
|
|
return GslRandomgen::gslalg_randomgeneratorTableSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
unsigned long GslRandomgen::rngType_getMinRand(const int index)
|
||
|
|
{
|
||
|
|
assert(index >= 0 && index < GslRandomgen::gslalg_randomgeneratorTableSize);
|
||
|
|
return GslRandomgen::gslalg_randomgeneratorTable[index]->max;
|
||
|
|
}
|
||
|
|
|
||
|
|
unsigned long GslRandomgen::rngType_getMaxRand(const int index)
|
||
|
|
{
|
||
|
|
assert(index >= 0 && index < GslRandomgen::gslalg_randomgeneratorTableSize);
|
||
|
|
return GslRandomgen::gslalg_randomgeneratorTable[index]->min;
|
||
|
|
}
|
||
|
|
|
||
|
|
std::string GslRandomgen::rngType_getName(const int index)
|
||
|
|
{
|
||
|
|
assert(index >= 0 && index < GslRandomgen::gslalg_randomgeneratorTableSize);
|
||
|
|
std::string res(GslRandomgen::gslalg_randomgeneratorTable[index]->name);
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Define static variables
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
bool GslRandomgen::initialized = false;
|
||
|
|
int GslRandomgen::gslalg_randomgeneratorTableSize = 0;
|
||
|
|
int GslRandomgen::gsl_rng_defaultIndex = 0;
|
||
|
|
const gsl_rng_type** GslRandomgen::gslalg_randomgeneratorTable = NULL;
|
||
|
|
|
||
|
|
/*
|
||
|
|
4 Secondo Datatypes
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
5 Operators
|
||
|
|
|
||
|
|
Common Type Mapping functions for this algebra:
|
||
|
|
|
||
|
|
----
|
||
|
|
gslalg_empty2int_TM: -> int
|
||
|
|
gslalg_empty2real_TM: -> real
|
||
|
|
gslalg_int2bool_TM: int -> bool
|
||
|
|
gslalg_int2int_TM: int -> int
|
||
|
|
gslalg_intint2bool_TM: int x int -> bool
|
||
|
|
gslalg_intreal2real_TM: int x real -> real
|
||
|
|
gslalg_intreal2int_TM: int x real -> int
|
||
|
|
gslalg_real2real_TM: real -> real
|
||
|
|
gslalg_real2int_TM: real -> int
|
||
|
|
gslalg_realreal2real_TM: real x real -> real
|
||
|
|
|
||
|
|
----
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
enum gslCcType { ccint, ccreal, ccerror, ccbool, ccstring, ccconst, ccset };
|
||
|
|
gslCcType gslTypeOfSymbol( ListExpr symbol )
|
||
|
|
{
|
||
|
|
if ( nl->AtomType( symbol ) == SymbolType )
|
||
|
|
{
|
||
|
|
std::string s = nl->SymbolValue( symbol );
|
||
|
|
if ( s == CcInt::BasicType() ) return (ccint);
|
||
|
|
if ( s == CcReal::BasicType() ) return (ccreal);
|
||
|
|
if ( s == CcBool::BasicType() ) return (ccbool);
|
||
|
|
if ( s == CcString::BasicType() ) return (ccstring);
|
||
|
|
if ( s == "const" ) return (ccconst);
|
||
|
|
if ( s == "set" ) return (ccset);
|
||
|
|
}
|
||
|
|
return (ccerror);
|
||
|
|
}
|
||
|
|
|
||
|
|
// int x int -> bool
|
||
|
|
ListExpr gslalg_intint2bool_TM ( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1, arg2;
|
||
|
|
if ( nl->ListLength( args ) == 2 )
|
||
|
|
{
|
||
|
|
arg1 = nl->First( args );
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
if ( gslTypeOfSymbol( arg1 ) == ccint && gslTypeOfSymbol( arg2 ) == ccint )
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom( CcBool::BasicType() ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ErrorReporter::ReportError("GSLAlgebra: Expected int x int.");
|
||
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// () -> int
|
||
|
|
ListExpr gslalg_empty2int_TM ( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( !nl->IsEmpty( args ) )
|
||
|
|
{
|
||
|
|
ErrorReporter::ReportError("GSLAlgebra: Expected empty list.");
|
||
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom( CcInt::BasicType() ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// () -> real
|
||
|
|
ListExpr gslalg_empty2real_TM ( ListExpr args )
|
||
|
|
{
|
||
|
|
if ( !nl->IsEmpty( args ) )
|
||
|
|
{
|
||
|
|
ErrorReporter::ReportError("GSLAlgebra: Expected empty list.");
|
||
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom( CcReal::BasicType() ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// int -> bool
|
||
|
|
ListExpr gslalg_int2bool_TM ( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1;
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
arg1 = nl->First( args );
|
||
|
|
if ( gslTypeOfSymbol( arg1 ) == ccint )
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom( CcBool::BasicType() ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ErrorReporter::ReportError("GSLAlgebra: Expected int.");
|
||
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// int -> int
|
||
|
|
ListExpr gslalg_int2int_TM ( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1;
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
arg1 = nl->First( args );
|
||
|
|
if ( gslTypeOfSymbol( arg1 ) == ccint )
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom( CcInt::BasicType() ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ErrorReporter::ReportError("GSLAlgebra: Expected int.");
|
||
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// real -> real
|
||
|
|
ListExpr gslalg_real2real_TM ( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1;
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
arg1 = nl->First( args );
|
||
|
|
if ( gslTypeOfSymbol( arg1 ) == ccreal )
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom( CcReal::BasicType() ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ErrorReporter::ReportError("GSLAlgebra: Expected real.");
|
||
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// real -> int
|
||
|
|
ListExpr gslalg_real2int_TM ( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1;
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
arg1 = nl->First( args );
|
||
|
|
if ( gslTypeOfSymbol( arg1 ) == ccreal )
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom( CcInt::BasicType() ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ErrorReporter::ReportError("GSLAlgebra: Expected real.");
|
||
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// int -> string
|
||
|
|
ListExpr gslalg_int2string_TM ( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1;
|
||
|
|
if ( nl->ListLength( args ) == 1 )
|
||
|
|
{
|
||
|
|
arg1 = nl->First( args );
|
||
|
|
if ( gslTypeOfSymbol( arg1 ) == ccint )
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom( CcString::BasicType() ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ErrorReporter::ReportError("GSLAlgebra: Expected int.");
|
||
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// real x real -> real
|
||
|
|
ListExpr gslalg_realreal2real_TM ( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1, arg2;
|
||
|
|
if ( nl->ListLength( args ) == 2 )
|
||
|
|
{
|
||
|
|
arg1 = nl->First( args );
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
if ( (gslTypeOfSymbol( arg1 ) == ccreal) &&
|
||
|
|
(gslTypeOfSymbol( arg2 ) == ccreal) )
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom( CcReal::BasicType() ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ErrorReporter::ReportError("GSLAlgebra: Expected real x real.");
|
||
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// int x real -> real
|
||
|
|
ListExpr gslalg_intreal2real_TM ( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1, arg2;
|
||
|
|
if ( nl->ListLength( args ) == 2 )
|
||
|
|
{
|
||
|
|
arg1 = nl->First( args );
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
if ( gslTypeOfSymbol( arg1 ) == ccint && gslTypeOfSymbol( arg2 ) == ccreal )
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom( CcReal::BasicType() ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ErrorReporter::ReportError("GSLAlgebra: Expected int x real.");
|
||
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// int x real -> real
|
||
|
|
ListExpr gslalg_intreal2int_TM ( ListExpr args )
|
||
|
|
{
|
||
|
|
ListExpr arg1, arg2;
|
||
|
|
if ( nl->ListLength( args ) == 2 )
|
||
|
|
{
|
||
|
|
arg1 = nl->First( args );
|
||
|
|
arg2 = nl->Second( args );
|
||
|
|
if ( gslTypeOfSymbol( arg1 ) == ccint && gslTypeOfSymbol( arg2 ) == ccreal )
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom( CcInt::BasicType() ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ErrorReporter::ReportError("GSLAlgebra: Expected int x real.");
|
||
|
|
return (nl->SymbolAtom( Symbol::TYPEERROR() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.0 Operator ~rng\_init~
|
||
|
|
|
||
|
|
Create and initialize the random number generator.
|
||
|
|
Always returns `TRUE'.
|
||
|
|
|
||
|
|
----
|
||
|
|
rng_init: int x int --> bool
|
||
|
|
|
||
|
|
----
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
// define static variables
|
||
|
|
// the static generator instance - initialize with defaults
|
||
|
|
static GslRandomgen the_gsl_randomgenerator( true );
|
||
|
|
|
||
|
|
int gslalg_rng_init_VM ( Word* args, Word& result, int message,
|
||
|
|
Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcBool *res = ((CcBool*)result.addr);
|
||
|
|
CcInt *arg1 = ((CcInt*)args[0].addr);
|
||
|
|
CcInt *arg2 = ((CcInt*)args[1].addr);
|
||
|
|
if ( arg1->IsDefined() && arg2->IsDefined() )
|
||
|
|
{
|
||
|
|
// overflow save implementation
|
||
|
|
long type = arg1->GetIntval();
|
||
|
|
unsigned long seed = arg2->GetIntval();
|
||
|
|
if( type >= 0 && type < GslRandomgen::rngType_getNoOfGenerators() )
|
||
|
|
{
|
||
|
|
the_gsl_randomgenerator = GslRandomgen(type, seed);
|
||
|
|
res->Set(true, true);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->Set(true, false);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->Set(true, false);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_init_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text>int x int -> bool</text--->"
|
||
|
|
"<text>rng_init( type, seed )</text--->"
|
||
|
|
"<text>Initialize the GSL random generator. Load generator type 'type' "
|
||
|
|
"and use random seed 'seed'.</text--->"
|
||
|
|
"<text>query rng_init(0, 0)</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_init(
|
||
|
|
"rng_init",
|
||
|
|
gslalg_rng_init_Spec,
|
||
|
|
gslalg_rng_init_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_intint2bool_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.1 Operator ~rng\_int~
|
||
|
|
|
||
|
|
Get the next int random number
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_int_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
long resL = the_gsl_randomgenerator.NextInt(); // implicit conversion!
|
||
|
|
res->Set(true, resL);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_int_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> -> int</text--->"
|
||
|
|
"<text>rng_int()</text--->"
|
||
|
|
"<text>Draw a uniformly distributed integer variate from the GSL random "
|
||
|
|
"number generator. To get minimum and maximum boundary for "
|
||
|
|
"random numbers, use rng_getMin() and rng_getMax().</text--->"
|
||
|
|
"<text>query randint()</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_int(
|
||
|
|
"rng_int",
|
||
|
|
gslalg_rng_int_Spec,
|
||
|
|
gslalg_rng_int_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_empty2int_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.2 Operator ~rng\_intN~
|
||
|
|
|
||
|
|
Get the next int random number
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_intN_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
CcInt *cN = ((CcInt*) args[0].addr);
|
||
|
|
long resL = 0;
|
||
|
|
if( cN->IsDefined() && cN->GetIntval() >= 1)
|
||
|
|
{
|
||
|
|
long N = cN->GetIntval();
|
||
|
|
resL = the_gsl_randomgenerator.NextIntN( N ); // implicit conversion!
|
||
|
|
res->Set(true, resL);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->Set(false, resL);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_intN_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> int -> int</text--->"
|
||
|
|
"<text>rng_intN( N )</text--->"
|
||
|
|
"<text>Draw a uniformly distributed integer variate from [0,N-1] using "
|
||
|
|
"the GSL random number generator. For N<1, undef will be returned."
|
||
|
|
"</text--->"
|
||
|
|
"<text>query rng_intN(6)+1</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_intN(
|
||
|
|
"rng_intN",
|
||
|
|
gslalg_rng_intN_Spec,
|
||
|
|
gslalg_rng_intN_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_int2int_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.3 Operator ~rng\_real~
|
||
|
|
|
||
|
|
Get the next real random number
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_real_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcReal *res = (CcReal*) result.addr;
|
||
|
|
double resD = the_gsl_randomgenerator.NextReal();
|
||
|
|
res->Set(true, resD);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_real_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> -> real</text--->"
|
||
|
|
"<text>rng_real( )</text--->"
|
||
|
|
"<text>Draw a uniformly distributed real variate from [0,1) using "
|
||
|
|
"the GSL random number generator.</text--->"
|
||
|
|
"<text>query floor((rng_real()*6))+1</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_real(
|
||
|
|
"rng_real",
|
||
|
|
gslalg_rng_real_Spec,
|
||
|
|
gslalg_rng_real_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_empty2real_TM) ;
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.4 Operator ~rng\_realpos~
|
||
|
|
|
||
|
|
Get the next positive real random number
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_realpos_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcReal *res = (CcReal*) result.addr;
|
||
|
|
double resD = the_gsl_randomgenerator.NextRealPos();
|
||
|
|
res->Set(true, resD);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_realpos_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> -> real</text--->"
|
||
|
|
"<text>rng_realpos( )</text--->"
|
||
|
|
"<text>Draw a uniformly distributed real variate from (0,1) using "
|
||
|
|
"the GSL random number generator.</text--->"
|
||
|
|
"<text>query floor((rng_realpos()*6))+1</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_realpos(
|
||
|
|
"rng_realpos",
|
||
|
|
gslalg_rng_realpos_Spec,
|
||
|
|
gslalg_rng_realpos_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_empty2real_TM) ;
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.5 Operator ~rng\_getMin~
|
||
|
|
|
||
|
|
Get the minimum random number
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_getMin_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
long resL = the_gsl_randomgenerator.MinRand(); // implicit conversion!
|
||
|
|
res->Set(true, resL);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_getMin_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> -> int</text--->"
|
||
|
|
"<text>rng_getMin()</text--->"
|
||
|
|
"<text>Get the minimum integer, that is generated by the GSL random "
|
||
|
|
"number generator.</text--->"
|
||
|
|
"<text>query rng_getMin()</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_getMin(
|
||
|
|
"rng_getMin",
|
||
|
|
gslalg_rng_getMin_Spec,
|
||
|
|
gslalg_rng_getMin_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_empty2int_TM) ;
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.6 Operator ~rng\_getMax~
|
||
|
|
|
||
|
|
Get the maximum random number
|
||
|
|
|
||
|
|
*/
|
||
|
|
int gslalg_rng_getMax_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = (CcInt*) result.addr;
|
||
|
|
long resL = the_gsl_randomgenerator.MaxRand(); // implicit conversion!
|
||
|
|
res->Set(true, resL);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_getMax_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> -> int</text--->"
|
||
|
|
"<text>rng_getMax()</text--->"
|
||
|
|
"<text>Get the maximum integer, that is generated by the GSL random "
|
||
|
|
"number generator.</text--->"
|
||
|
|
"<text>query rng_getMax()</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_getMax(
|
||
|
|
"rng_getMax",
|
||
|
|
gslalg_rng_getMax_Spec,
|
||
|
|
gslalg_rng_getMax_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_empty2int_TM) ;
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.7 Operator ~rng\_setSeed~
|
||
|
|
|
||
|
|
Set a new seed for the specified random number generator and reinitialize it.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_setSeed_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcBool *res = ((CcBool*) result.addr);
|
||
|
|
CcInt *cN = ((CcInt*) args[0].addr);
|
||
|
|
if( cN->IsDefined() )
|
||
|
|
{
|
||
|
|
long N = cN->GetIntval();
|
||
|
|
the_gsl_randomgenerator.SetSeed( N ); // implicit conversion!
|
||
|
|
res->Set(true, true);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->Set(true, false);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_setSeed_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> int -> bool</text--->"
|
||
|
|
"<text>rng_setSeed( N )</text--->"
|
||
|
|
"<text>Reinitialize the GSL random number generator with seed N.</text--->"
|
||
|
|
"<text>query rng_setSeed(6)</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_setSeed(
|
||
|
|
"rng_setSeed",
|
||
|
|
gslalg_rng_setSeed_Spec,
|
||
|
|
gslalg_rng_setSeed_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_int2bool_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.7 Operator ~rng\_getSeed~
|
||
|
|
|
||
|
|
get the seed value for the random number generator.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_getSeed_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
long N = the_gsl_randomgenerator.GetSeed();
|
||
|
|
res->Set(true, N);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_getSeed_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> -> int</text--->"
|
||
|
|
"<text>rng_getSeed( N )</text--->"
|
||
|
|
"<text>Get the seed used for the GSL random number generator.</text--->"
|
||
|
|
"<text>query rng_getSeed()</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
|
||
|
|
Operator gslalg_rng_getSeed(
|
||
|
|
"rng_getSeed",
|
||
|
|
gslalg_rng_getSeed_Spec,
|
||
|
|
gslalg_rng_getSeed_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_empty2int_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.8 Operator ~rng\_flat~
|
||
|
|
|
||
|
|
Get a flat (uniform) distributed variate from randomgen
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_flat_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcReal *res = ((CcReal*) result.addr);
|
||
|
|
double resD = 0;
|
||
|
|
CcReal *cA = (CcReal*) args[0].addr;
|
||
|
|
CcReal *cB = (CcReal*) args[1].addr;
|
||
|
|
if( cA->IsDefined() && cB->IsDefined() )
|
||
|
|
{
|
||
|
|
double a = cA->GetRealval();
|
||
|
|
double b = cB->GetRealval();
|
||
|
|
if( a <= b )
|
||
|
|
{
|
||
|
|
resD = gsl_ran_flat(the_gsl_randomgenerator.GetGenerator(), a, b);
|
||
|
|
res->Set(true, resD);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
res->Set(false, 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->Set(false, 0);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_flat_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> real x real -> real</text--->"
|
||
|
|
"<text>rng_flat( Min, Max )</text--->"
|
||
|
|
"<text>Get a flat (uniform) distributed variate from [Min, Max] using "
|
||
|
|
"the GSL random number generator.</text--->"
|
||
|
|
"<text>query rng_flat( -5.5, 14.7 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_flat(
|
||
|
|
"rng_flat",
|
||
|
|
gslalg_rng_flat_Spec,
|
||
|
|
gslalg_rng_flat_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_realreal2real_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.9 Operator ~rng\_binomial~
|
||
|
|
|
||
|
|
Get a binomial distributed variate from randomgen
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
//Operator gslalg_rng_binomial;
|
||
|
|
|
||
|
|
int gslalg_rng_binomial_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
long resL = 0;
|
||
|
|
CcInt *cN = (CcInt*) args[0].addr;
|
||
|
|
CcReal *cP = (CcReal*) args[1].addr;
|
||
|
|
if( cN->IsDefined() && cP->IsDefined() )
|
||
|
|
{
|
||
|
|
double p = cP->GetRealval();
|
||
|
|
long n = cN->GetIntval();
|
||
|
|
if( n >= 0 && p >= 0 && p <= 1.0 )
|
||
|
|
{
|
||
|
|
resL = gsl_ran_binomial(the_gsl_randomgenerator.GetGenerator(), p, n);
|
||
|
|
res->Set(true, resL);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
res->Set(false, 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->Set(false, 0);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_binomial_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> int x real -> int</text--->"
|
||
|
|
"<text>rng_binomial( N, P )</text--->"
|
||
|
|
"<text>This function returns a random integer from the binomial "
|
||
|
|
"distribution, the number of successes in N independent trials "
|
||
|
|
"with probability P, using the GSL random generator.</text--->"
|
||
|
|
"<text>query rng_binomial( 10, 0.4 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_binomial(
|
||
|
|
"rng_binomial",
|
||
|
|
gslalg_rng_binomial_Spec,
|
||
|
|
gslalg_rng_binomial_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_intreal2int_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.10 Operator ~rng\_gaussian~
|
||
|
|
|
||
|
|
Get a gaussian distributed variate from randomgen
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_gaussian_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcReal *res = ((CcReal*) result.addr);
|
||
|
|
double resD = 0;
|
||
|
|
CcReal *cSigma = (CcReal*) args[0].addr;
|
||
|
|
if( cSigma->IsDefined() )
|
||
|
|
{
|
||
|
|
double sigma = cSigma->GetRealval();
|
||
|
|
resD = gsl_ran_gaussian(the_gsl_randomgenerator.GetGenerator(), sigma);
|
||
|
|
res->Set(true, resD);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->Set(false, 0);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_gaussian_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> real -> real</text--->"
|
||
|
|
"<text>rng_gaussian( Sigma )</text--->"
|
||
|
|
"<text>Get a Gaussian distributed real variate with mean zero "
|
||
|
|
"and standard deviation Sigma using "
|
||
|
|
"the GSL random number generator.</text--->"
|
||
|
|
"<text>query rng_gaussian( 0.4 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
|
||
|
|
Operator gslalg_rng_gaussian(
|
||
|
|
"rng_gaussian",
|
||
|
|
gslalg_rng_gaussian_Spec,
|
||
|
|
gslalg_rng_gaussian_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_real2real_TM) ;
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.11 Operator ~rng\_exponential~
|
||
|
|
|
||
|
|
Get a gaussian distributed variate from randomgen
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_exponential_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcReal *res = (CcReal*) result.addr;
|
||
|
|
CcReal *cMu = (CcReal*) args[0].addr;
|
||
|
|
if( cMu->IsDefined() )
|
||
|
|
{
|
||
|
|
double Mu = cMu->GetRealval();
|
||
|
|
double resD = gsl_ran_exponential(the_gsl_randomgenerator.GetGenerator(),
|
||
|
|
Mu);
|
||
|
|
res->Set(true, resD);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->Set(false, 0);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_exponential_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> real -> real</text--->"
|
||
|
|
"<text>rng_exponential( Mu )</text--->"
|
||
|
|
"<text>Get a exponentially distributed real variate with mean Mu "
|
||
|
|
"using the GSL random number generator.</text--->"
|
||
|
|
"<text>query rng_exponential( 0.4 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
|
||
|
|
Operator gslalg_rng_exponential(
|
||
|
|
"rng_exponential",
|
||
|
|
gslalg_rng_exponential_Spec,
|
||
|
|
gslalg_rng_exponential_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_real2real_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.12 Operator ~rng\_getType~
|
||
|
|
|
||
|
|
get the random generator' type index
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_getType_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
long N = the_gsl_randomgenerator.GetType();
|
||
|
|
res->Set(true, N);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_getType_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> -> int</text--->"
|
||
|
|
"<text>rng_getType( N )</text--->"
|
||
|
|
"<text>Get the random generator's type index used for the GSL "
|
||
|
|
"random number generator.</text--->"
|
||
|
|
"<text>query rng_getType()</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
|
||
|
|
Operator gslalg_rng_getType(
|
||
|
|
"rng_getType",
|
||
|
|
gslalg_rng_getType_Spec,
|
||
|
|
gslalg_rng_getType_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_empty2int_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.13 Operator ~rng\_NoGenerators~
|
||
|
|
|
||
|
|
return the number of available GSL random number generator types.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_NoGenerators_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
long N = GslRandomgen::rngType_getNoOfGenerators();
|
||
|
|
res->Set(true, N);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_NoGenerators_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> -> int</text--->"
|
||
|
|
"<text>rng_NoGenerators( N )</text--->"
|
||
|
|
"<text>Get the number of available GSL random number "
|
||
|
|
"generator types.</text--->"
|
||
|
|
"<text>query rng_NoGenerators()</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_NoGenerators(
|
||
|
|
"rng_NoGenerators",
|
||
|
|
gslalg_rng_NoGenerators_Spec,
|
||
|
|
gslalg_rng_NoGenerators_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_empty2int_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.14 Operator ~rng\_GeneratorName~
|
||
|
|
|
||
|
|
return the number of available GSL random number generator types.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_GeneratorName_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcString *res = ((CcString*) result.addr);
|
||
|
|
CcInt *cIndex = (CcInt*) args[0].addr;
|
||
|
|
if( cIndex->IsDefined() )
|
||
|
|
{
|
||
|
|
int index = cIndex->GetIntval();
|
||
|
|
if( index >=0 && index < GslRandomgen::rngType_getNoOfGenerators() )
|
||
|
|
{
|
||
|
|
res->Set( true, (GslRandomgen::rngType_getName(index)) );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->SetDefined( false );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->SetDefined( false );
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_GeneratorName_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> int -> string</text--->"
|
||
|
|
"<text>rng_GeneratorName( N )</text--->"
|
||
|
|
"<text>Get the name of the GSL random number "
|
||
|
|
"generator type with index N.</text--->"
|
||
|
|
"<text>query rng_GeneratorName( 1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_GeneratorName(
|
||
|
|
"rng_GeneratorName",
|
||
|
|
gslalg_rng_GeneratorName_Spec,
|
||
|
|
gslalg_rng_GeneratorName_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_int2string_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.15 Operator ~rng\_GeneratorMinRand~
|
||
|
|
|
||
|
|
Return the minimum number generated by the specified GSL random number
|
||
|
|
generator type.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_GeneratorMinRand_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
CcInt *cIndex = (CcInt*) args[0].addr;
|
||
|
|
if( cIndex->IsDefined() )
|
||
|
|
{
|
||
|
|
int index = cIndex->GetIntval();
|
||
|
|
if( index >=0 && index < GslRandomgen::rngType_getNoOfGenerators() )
|
||
|
|
{
|
||
|
|
res->Set( true, (GslRandomgen::rngType_getMinRand(index)) );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->SetDefined( false );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->SetDefined( false );
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_GeneratorMinRand_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> int -> int</text--->"
|
||
|
|
"<text>rng_GeneratorMinRand( N )</text--->"
|
||
|
|
"<text>Get the minimum number generated by the specified GSL "
|
||
|
|
"random number generator type N.</text--->"
|
||
|
|
"<text>query rng_GeneratorMinRand( 1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_GeneratorMinRand(
|
||
|
|
"rng_GeneratorMinRand",
|
||
|
|
gslalg_rng_GeneratorMinRand_Spec,
|
||
|
|
gslalg_rng_GeneratorMinRand_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_int2int_TM) ;
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.16 Operator ~rng\_GeneratorMaxRand~
|
||
|
|
|
||
|
|
Return the maximum number generated by the specified GSL random number
|
||
|
|
generator type.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_GeneratorMaxRand_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
CcInt *cIndex = (CcInt*) args[0].addr;
|
||
|
|
if( cIndex->IsDefined() )
|
||
|
|
{
|
||
|
|
int index = cIndex->GetIntval();
|
||
|
|
if( index >=0 && index < GslRandomgen::rngType_getNoOfGenerators() )
|
||
|
|
{
|
||
|
|
res->Set( true, (GslRandomgen::rngType_getMaxRand(index)) );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->SetDefined( false );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->SetDefined( false );
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_GeneratorMaxRand_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> int -> int</text--->"
|
||
|
|
"<text>rng_GeneratorMaxRand( N )</text--->"
|
||
|
|
"<text>Get the maximum number generated by the specified GSL "
|
||
|
|
"random number generator type N.</text--->"
|
||
|
|
"<text>query rng_GeneratorMaxRand( 1 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_GeneratorMaxRand(
|
||
|
|
"rng_GeneratorMaxRand",
|
||
|
|
gslalg_rng_GeneratorMaxRand_Spec,
|
||
|
|
gslalg_rng_GeneratorMaxRand_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_int2int_TM) ;
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.17 Operator ~rng\_TypeDescriptors~
|
||
|
|
|
||
|
|
get a stream of tuples describing all available GSL random number generators.
|
||
|
|
tuple format is tuple((Index int)(MinInt int)(MaxInt int)(Name string)).
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int rng_TypeDescriptors_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
long N = the_gsl_randomgenerator.GetType();
|
||
|
|
res->Set(true, N);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string rng_TypeDescriptors_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> -> stream(tuple((Index int)(MinInt int)(MaxInt int)"
|
||
|
|
"(Name string)))</text--->"
|
||
|
|
"<text>rng_TypeDescriptors( )</text--->"
|
||
|
|
"<text>Get a tuple stream of all available GSL random number "
|
||
|
|
"generators.</text--->"
|
||
|
|
"<text>query rng_TypeDescriptors( ) consume</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator rng_TypeDescriptors(
|
||
|
|
"rng_TypeDescriptors",
|
||
|
|
gslalg_rng_getType_Spec,
|
||
|
|
gslalg_rng_getType_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_empty2int_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.18 Operator ~rng\_poisson~
|
||
|
|
|
||
|
|
Get a poisson distributed int variate from randomgen
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_poisson_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
long resD = 0;
|
||
|
|
CcReal *cA = (CcReal*) args[0].addr;
|
||
|
|
if( cA->IsDefined() )
|
||
|
|
{
|
||
|
|
double a = cA->GetRealval();
|
||
|
|
resD = gsl_ran_poisson(the_gsl_randomgenerator.GetGenerator(), a);
|
||
|
|
res->Set(true, resD);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->Set(false, 0);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_poisson_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> real -> int</text--->"
|
||
|
|
"<text>rng_poisson( Mu )</text--->"
|
||
|
|
"<text>Returns a random integer from the Poisson distribution with "
|
||
|
|
"mean Mu using the GSL random number generator.</text--->"
|
||
|
|
"<text>query rng_poisson( )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_poisson(
|
||
|
|
"rng_poisson",
|
||
|
|
gslalg_rng_poisson_Spec,
|
||
|
|
gslalg_rng_poisson_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_real2int_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.19 Operator ~rng\_geometric~
|
||
|
|
|
||
|
|
Get a geometric distributed int variate from randomgen
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
int gslalg_rng_geometric_VM ( Word* args, Word& result,
|
||
|
|
int message, Word& local, Supplier s )
|
||
|
|
{
|
||
|
|
result = qp->ResultStorage( s );
|
||
|
|
CcInt *res = ((CcInt*) result.addr);
|
||
|
|
long resD = 0;
|
||
|
|
CcReal *cA = (CcReal*) args[0].addr;
|
||
|
|
if( cA->IsDefined() )
|
||
|
|
{
|
||
|
|
double a = cA->GetRealval();
|
||
|
|
if( 0.0 <= a && a <= 1.0 )
|
||
|
|
{
|
||
|
|
resD = gsl_ran_geometric(the_gsl_randomgenerator.GetGenerator(), a);
|
||
|
|
res->Set(true, resD);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
res->Set(false, 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
res->Set(false, 0);
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::string gslalg_rng_geometric_Spec =
|
||
|
|
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" )"
|
||
|
|
"( <text> real x real -> int</text--->"
|
||
|
|
"<text>rng_geometric( p )</text--->"
|
||
|
|
"<text>Returns a random integer from the geometric distribution, "
|
||
|
|
"the number of independent trials with probability p until the first "
|
||
|
|
"success. Uses the GSL random number generator.</text--->"
|
||
|
|
"<text>query rng_geometric( 0.75 )</text--->"
|
||
|
|
") )";
|
||
|
|
|
||
|
|
Operator gslalg_rng_geometric(
|
||
|
|
"rng_geometric",
|
||
|
|
gslalg_rng_geometric_Spec,
|
||
|
|
gslalg_rng_geometric_VM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
gslalg_real2int_TM) ;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
6 Class ~GSLAlgebra~
|
||
|
|
|
||
|
|
The last steps in adding an algebra to the Secondo system are
|
||
|
|
|
||
|
|
* Associating value mapping functions with their operators
|
||
|
|
|
||
|
|
* ``Bunching'' all
|
||
|
|
type constructors and operators in one instance of class ~Algebra~.
|
||
|
|
|
||
|
|
Therefore, a new subclass ~GSLAlgebra~ of class ~Algebra~ is declared. The only
|
||
|
|
specialization with respect to class ~Algebra~ takes place within the
|
||
|
|
constructor: all type constructors and operators are registered at the actual algebra.
|
||
|
|
|
||
|
|
After declaring the new class, its only instance ~ccalgebra1~ is defined.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
class GSLAlgebra : public Algebra
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
GSLAlgebra() : Algebra()
|
||
|
|
{
|
||
|
|
AddOperator( &gslalg_rng_init );
|
||
|
|
AddOperator( &gslalg_rng_int );
|
||
|
|
AddOperator( &gslalg_rng_intN );
|
||
|
|
AddOperator( &gslalg_rng_getMin );
|
||
|
|
AddOperator( &gslalg_rng_getMax );
|
||
|
|
AddOperator( &gslalg_rng_real );
|
||
|
|
AddOperator( &gslalg_rng_realpos );
|
||
|
|
AddOperator( &gslalg_rng_setSeed );
|
||
|
|
AddOperator( &gslalg_rng_getSeed );
|
||
|
|
AddOperator( &gslalg_rng_getType );
|
||
|
|
AddOperator( &gslalg_rng_flat );
|
||
|
|
AddOperator( &gslalg_rng_gaussian );
|
||
|
|
AddOperator( &gslalg_rng_binomial );
|
||
|
|
AddOperator( &gslalg_rng_geometric );
|
||
|
|
AddOperator( &gslalg_rng_exponential );
|
||
|
|
AddOperator( &gslalg_rng_poisson );
|
||
|
|
AddOperator( &gslalg_rng_NoGenerators );
|
||
|
|
AddOperator( &gslalg_rng_GeneratorName );
|
||
|
|
AddOperator( &gslalg_rng_GeneratorMinRand );
|
||
|
|
AddOperator( &gslalg_rng_GeneratorMaxRand );
|
||
|
|
}
|
||
|
|
~GSLAlgebra() {};
|
||
|
|
|
||
|
|
// private:
|
||
|
|
// bool initialized;
|
||
|
|
// const gsl_rng_type **gslalg_randomgeneratorTable;
|
||
|
|
// // number of generator types available:
|
||
|
|
// int gslalg_randomgeneratorTableSize;
|
||
|
|
// int gsl_rng_defaultIndex;
|
||
|
|
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
/*
|
||
|
|
7 Initialization
|
||
|
|
|
||
|
|
Each algebra module needs an initialization function. The algebra manager
|
||
|
|
has a reference to this function if this algebra is included in the list
|
||
|
|
of required algebras, thus forcing the linker to include this module.
|
||
|
|
|
||
|
|
The algebra manager invokes this function to get a reference to the instance
|
||
|
|
of the algebra class and to provide references to the global nested list
|
||
|
|
container (used to store constructor, type, operator and object information)
|
||
|
|
and to the query processor.
|
||
|
|
|
||
|
|
The function has a C interface to make it possible to load the algebra
|
||
|
|
dynamically at runtime.
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
extern "C"
|
||
|
|
Algebra*
|
||
|
|
InitializeGSLAlgebra( NestedList* nlRef, QueryProcessor* qpRef )
|
||
|
|
{
|
||
|
|
nl = nlRef;
|
||
|
|
qp = qpRef;
|
||
|
|
return (new GSLAlgebra());
|
||
|
|
}
|