New command 'setseed' with function com_sseed

to set the random number generator
This commit is contained in:
Holger Vogt 2018-07-01 16:26:53 +02:00
parent 8fbcb16a57
commit 7ca61b3c98
5 changed files with 88 additions and 12 deletions

View File

@ -83,6 +83,7 @@
#include "resource.h"
#include "diff.h"
#include "com_strcmp.h"
#include "ngspice/randnumb.h"
#include "arg.h"
@ -193,6 +194,10 @@ struct comm spcp_coms[] = {
{ 040000, 0, 0, 0 }, E_DEFHMASK, 0, 1,
NULL,
"[vecname] : Change default scale of current working plot." } ,
{ "setseed", com_sseed, FALSE, FALSE,
{ 04, 0, 0, 0 }, E_DEFHMASK, 0, 1,
NULL,
"[seed value] : Reset the random number generator with new seed value." } ,
{ "transpose", com_transpose, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
NULL,
@ -666,6 +671,10 @@ struct comm nutcp_coms[] = {
{ 040000, 0, 0, 0 }, E_DEFHMASK, 0, 1,
NULL,
"[vecname] : Change default scale of current working plot." } ,
{ "setseed", com_sseed, FALSE, FALSE,
{ 04, 0, 0, 0 }, E_DEFHMASK, 0, 1,
NULL,
"[seed value] : Reset the random number generator with new seed value." } ,
{ "transpose", com_transpose, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
NULL,

View File

@ -1,12 +1,17 @@
#ifndef ngspice_RANDNUMB_H
#define ngspice_RANDNUMB_H
#include "ngspice/wordlist.h"
extern void com_sseed(wordlist *wl);
extern void setseedinfo(void);
/* initialize random number generators */
extern void initw(void);
extern void checkseed(void); /* seed random or set by 'set rndseed=value'*/
extern double drand(void);
extern double gauss0(void);
extern double gauss1(void);
extern int poisson(double);
extern double exprand(double);

View File

@ -864,8 +864,10 @@ main(int argc, char **argv)
cp_program = ft_sim->simulator;
srand((unsigned int) getpid());
TausSeed();
/* initialze random number generator with seed = 1 */
int ii = 1;
cp_vset("rndseed", CP_NUM, &ii);
com_sseed(NULL);
/* --- Process command line options --- */
for (;;) {

View File

@ -65,6 +65,7 @@ double CombLCGTaus(void);
float CombLCGTaus2(void);
void rgauss(double* py1, double* py2);
static bool seedinfo = FALSE;
/* Check if a seed has been set by the command 'set rndseed=value'
@ -213,6 +214,23 @@ double gauss0(void)
}
}
/*** gauss ***
to be reproducible, we just use one value per pass */
double gauss1(void)
{
double fac, r, v1, v2;
do {
v1 = 2.0 * CombLCGTaus() - 1.0;
v2 = 2.0 * CombLCGTaus() - 1.0;
r = v1 * v1 + v2 * v2;
} while (r >= 1.0);
/* printf("v1 %f, v2 %f\n", v1, v2); */
fac = sqrt(-2.0 * log(r) / r);
return v2 * fac;
}
/* Polar form of the Box-Muller generator for Gaussian distributed
random variates.
Generator will be fed with two uniformly distributed random variates.
@ -264,3 +282,51 @@ double exprand(double mean)
expval = -log(CombLCGTaus()) * mean;
return expval;
}
/* seed random number generators immediately
* command "setseed"
* take value of variable rndseed as seed
* command "setseed <n>"
* seed with number <n>
*/
void
com_sseed(wordlist *wl)
{
int newseed;
if (wl == NULL) {
if (!cp_getvar("rndseed", CP_NUM, &newseed)) {
newseed = getpid();
cp_vset("rndseed", CP_NUM, &newseed);
}
srand((unsigned int)newseed);
TausSeed();
}
else if ((sscanf(wl->wl_word, " %d ", &newseed) != 1) ||
(newseed <= 0) || (newseed > INT_MAX))
{
fprintf(cp_err,
"\nWarning: Cannot use %s as seed!\n"
" Command 'setseed %s' ignored.\n\n",
wl->wl_word, wl->wl_word);
return;
}
else {
srand((unsigned int)newseed);
TausSeed();
cp_vset("rndseed", CP_NUM, &newseed);
}
if (seedinfo)
printf("\nSeed value for random number generator is set to %d\n", newseed);
}
void
setseedinfo(void)
{
seedinfo = TRUE;
}

View File

@ -648,8 +648,10 @@ ngSpice_Init(SendChar* printfcn, SendStat* statusfcn, ControlledExit* ngspiceexi
/* program name*/
cp_program = ft_sim->simulator;
srand((unsigned int) getpid());
TausSeed();
/* initialze random number generator with seed = 1 */
int ii = 1;
cp_vset("rndseed", CP_NUM, &ii);
com_sseed(NULL);
/* set a boolean variable to be used in .control sections */
bool sm = TRUE;
@ -741,15 +743,7 @@ bot:
fprintf (cp_out, "SoS %f, seed value: %ld\n", renormalize(), rseed);
}
#elif defined (WaGauss)
{
unsigned int rseed = 66;
if (!cp_getvar("rndseed", CP_NUM, &rseed, 0)) {
time_t acttime = time(NULL);
rseed = (unsigned int) acttime;
}
srand(rseed);
initw();
}
#endif
// com_version(NULL);