//-*- mode: c++; indent-tabs-mode-nil; coding: utf-8; show-trailing-whitespace: t -*- // file random.cpp #include "random.hpp" namespace randomize { // Variables. // Functions. double seedy(std::string *atim) { // // This function is designed to take the time of day (wall-clock // time) in bcd form as input, and return the number of seconds // since midnight as output. The time of day is assumed to be // coded in words atim(1) and atim(2) , as found by a call to // subroutine 'time44' . The storage here is in format 2a4 , // with the first four characters of 'hh.mm.ss' assumed to be // in atim(1) , and the last four in atim(2) . // // int amin; int hour; int ihr, imin, imin10, imin1, isec; int sec; double nReturnValue; // if (atim) { if (0 < sscanf(atim[ 0 ].c_str(), "%2d %1d", &ihr, &imin10)) { if (0 < sscanf(atim[ 1 ].c_str(), "%1d %2d", &imin1, &isec)) { imin = imin10 * 10 + imin1; hour = ihr * 3600; amin = imin * 60; sec = isec; nReturnValue = sec + amin + hour + 1.0; } } } return nReturnValue; } double randnm(const double &x) { // // This is a random number generating function, whose purpose is to // return with a value for a random variable which is uniformly- // distributed over the interval from zero to unity. // A typical call is y = randnm(x) , where 'x' is a // floating-point variable which is present only because 'random' // number-generating algorithms are never truly random, and generally // require some sort of 'random' initialization to even get started. // Since such number-generating algorithms are actually cyclic if a // large enough sampling is taken, it is also desirable to // re-initialize the algorithm periodically, by means of a 'random' // external input. Variable 'x' is this 'random' input, whose // purpose is to randomly re-initialize the algorithm, as follows ... // 1. If 'x' is identically zero, there is no initialization. // the next random number is simply returned through the // function name. // 2. If 'x' is positive, the random number generating // algorithm is to be initialized. EMTP usage has 'x' // as the wall-clock time in seconds since midnight, an // integer (though stored in floating-point mode, note). // In this case, no random number need be returned with the // function name, since the emtp will not use it. // If a non-cdc user has access to a random number generating // function which does not require initialization, he may simply // ignore 'x' , and return the random number through the function // name every time this module is called. // // A minus sign appended to variable 'xmaxmx' of /blank/ is a // flag that the user wants to employ the standard table of random // numbers which is built into module 'sandnm' . // // Installation-dependent emtp module written for the dec // VAX-11/780. 'ran' is a DEC system subroutine which // returns a random number uniformly distributed over (0, 1) . long int *pKnt; long int n14; double nReturnValue = 0.0; // pKnt = &blkcom::sMonCar.m_nKnt; if (blkcom::nXMaxMX >= 0.0) { if (x != 0.0) { if (*pKnt > 1) return nReturnValue; n14 = (int) x; if (n14 / 2 * 2 == n14) ++n14; } nReturnValue = rand() % n14; return nReturnValue; } nReturnValue = sandnm(x); return nReturnValue; } double sandnm(const double &x) { // This version of 'randnm' is used for testing of the // statistical overvoltage capability of the EMTP only. It uses // built-in random numbers, so as to produce identical results // on all computer systems, thereby permitting comparative // verification of results exactly as for conventional test cases. // In order to avoid re-use of random numbers, the number of // energizations 'nenerg' times the number of switches 'kswtch' // must not exceed the dimension of array 'a' . // If 'statistics' miscellaneous data parameter 'xmaxmx' // is input by the user with negative value, the EMTP takes // this to mean that "sandnm" is to be used for random // numbers rather than "randnm" . long int *pKnt; long int l = 0; long int n1; double a[ 100 ] = { .1445312506618, .8477795260409, .8267723125831, .6660710406131, .7152322826372, .3239128029543, .5051959208554, .3805491872180, .5609474043286, .5996361115942, .4159594349328, .6756609755246, .0995378032610, .6033780421273, .4515533431030, .0020932062778, .9161858062074, .3434229008090, .7876940045781, .2760908032985, .3665660303205, .8204300122029, .2413831265551, .1246653115746, .2802441882439, .0466535013838, .4742772736449, .9477027545777, .2260144770748, .2987460629005, .5203589181526, .8981967037721, .3873885562436, .5780913804991, .1280852320759, .3327754064471, .4043867414456, .9490362532099, .6261391859471, .3291406705415, .3366864607083, .9438413593777, .9369008057740, .0713971670442, .6500854844946, .9737952005663, .6485758973471, .7724301318424, .9676692044394, .5163953619955, .5788464270596, .7758933795560, .0910635448877, .0439510552688, .0707223001462, .9379043319315, .0052391978463, .9420572226295, .5932597508799, .6466146627873, .4395400252824, .1972895298303, .5017482047726, .1503404202877, .9624699228977, .0098276069324, .6571365402082, .4233003554891, .1203194365765, .7436871629477, .8136524161969, .7311319136405, .0594772166524, .2374863512189, .2450459940689, .4326371816340, .3562832359564, .3723442477773, .1694432139356, .3735622812899, .0610718353086, .2782657746530, .5137050416289, .4340395038268, .5766543446808, .4413641042052, .9812390285872, .2625281459037, .9554345097074, .4741647690234, .9906793757886, .7820837820369, .2206664815389, .0901816247992, .7625227133400, .4434728419824, .7905859532294, .9796097207935, .7599602497147, .1154361048406 }; double nReturnValue; // pKnt = &blkcom::sMonCar.m_nKnt; if (x != 0.0) l = (*pKnt - 1) * blkcom::nKSwtch + 1; else ++l; n1 = (l - 1) / 100; if (blkcom::nIprsUp >= 1) (*reinterpret_cast (blkcom::pLFiles[ 5 ])) << std::endl << " Variables in 'sandnm', the random number generator with 100 built-in numbers. l knt kswtch n1 , x" << std::endl << std::string(82, ' ') << l << *pKnt << blkcom::nKSwtch << n1 << x << std::endl; if (n1 > 0) l -= 100 * n1; nReturnValue = a[ l - 1 ]; return nReturnValue; } } // end of file random.cpp