📄 simlib.c
字号:
if (row == tail[LIST_EVENT]) {
/* Double check to see that this is a match. */
if ((value > low) && (value < high)) {
list_remove(LAST, LIST_EVENT);
return 1;
}
else /* no match */
return 0;
}
/* Check to see if this is the head of the list. If it is at the head, then
it MUST be a match. */
if (row == head[LIST_EVENT]) {
list_remove(FIRST, LIST_EVENT);
return 1;
}
/* Else remove this event somewhere in the middle of the event list. */
/* Update pointers. */
ahead = (*row).sr;
behind = (*row).pr;
(*behind).sr = ahead;
(*ahead).pr = behind;
/* Decrement the size of the event list. */
list_size[LIST_EVENT]--;
/* Copy and free memory. */
free((char *)transfer); /* Free the old transfer. */
transfer = (*row).value; /* Transfer the data. */
free((char *)row); /* Free the space vacated by row. */
/* Update the area under the number-in-event-list curve. */
timest((float)list_size[LIST_EVENT], TIM_VAR + LIST_EVENT);
return 1;
}
float sampst(float value, int variable)
{
/* Initialize, update, or report statistics on discrete-time processes:
sum/average, max (default -1E30), min (default 1E30), number of observations
for sampst variable "variable", where "variable":
= 0 initializes accumulators
> 0 updates sum, count, min, and max accumulators with new observation
< 0 reports stats on variable "variable" and returns them in transfer:
[1] = average of observations
[2] = number of observations
[3] = maximum of observations
[4] = minimum of observations */
static int ivar, num_observations[SVAR_SIZE];
static float max[SVAR_SIZE], min[SVAR_SIZE], sum[SVAR_SIZE];
/* If the variable value is improper, stop the simulation. */
if(!(variable >= -MAX_SVAR) && (variable <= MAX_SVAR)) {
printf("\n%d is an improper value for a sampst variable at time %f\n",
variable, sim_time);
exit(1);
}
/* Execute the desired option. */
if(variable > 0) { /* Update. */
sum[variable] += value;
if(value > max[variable]) max[variable] = value;
if(value < min[variable]) min[variable] = value;
num_observations[variable]++;
return 0.0;
}
if(variable < 0) { /* Report summary statistics in transfer. */
ivar = -variable;
transfer[2] = (float) num_observations[ivar];
transfer[3] = max[ivar];
transfer[4] = min[ivar];
if(num_observations[ivar] == 0)
transfer[1] = 0.0;
else
transfer[1] = sum[ivar] / transfer[2];
return transfer[1];
}
/* Initialize the accumulators. */
for(ivar=1; ivar <= MAX_SVAR; ++ivar) {
sum[ivar] = 0.0;
max[ivar] = -INFINITY;
min[ivar] = INFINITY;
num_observations[ivar] = 0;
}
}
float timest(float value, int variable)
{
/* Initialize, update, or report statistics on continuous-time processes:
integral/average, max (default -1E30), min (default 1E30)
for timest variable "variable", where "variable":
= 0 initializes counters
> 0 updates area, min, and max accumulators with new level of variable
< 0 reports stats on variable "variable" and returns them in transfer:
[1] = time-average of variable updated to the time of this call
[2] = maximum value variable has attained
[3] = minimum value variable has attained
Note that variables TIM_VAR + 1 through TVAR_SIZE are used for automatic
record keeping on the length of lists 1 through MAX_LIST. */
int ivar;
static float area[TVAR_SIZE], max[TVAR_SIZE], min[TVAR_SIZE],
preval[TVAR_SIZE], tlvc[TVAR_SIZE], treset;
/* If the variable value is improper, stop the simulation. */
if(!(variable >= -MAX_TVAR) && (variable <= MAX_TVAR)) {
printf("\n%d is an improper value for a timest variable at time %f\n",
variable, sim_time);
exit(1);
}
/* Execute the desired option. */
if(variable > 0) { /* Update. */
area[variable] += (sim_time - tlvc[variable]) * preval[variable];
if(value > max[variable]) max[variable] = value;
if(value < min[variable]) min[variable] = value;
preval[variable] = value;
tlvc[variable] = sim_time;
return 0.0;
}
if(variable < 0) { /* Report summary statistics in transfer. */
ivar = -variable;
area[ivar] += (sim_time - tlvc[ivar]) * preval[ivar];
tlvc[ivar] = sim_time;
transfer[1] = area[ivar] / (sim_time - treset);
transfer[2] = max[ivar];
transfer[3] = min[ivar];
return transfer[1];
}
/* Initialize the accumulators. */
for(ivar = 1; ivar <= MAX_TVAR; ++ivar) {
area[ivar] = 0.0;
max[ivar] = -INFINITY;
min[ivar] = INFINITY;
preval[ivar] = 0.0;
tlvc[ivar] = sim_time;
}
treset = sim_time;
}
float filest(int list)
{
/* Report statistics on the length of list "list" in transfer:
[1] = time-average of list length updated to the time of this call
[2] = maximum length list has attained
[3] = minimum length list has attained
This uses timest variable TIM_VAR + list. */
return timest(0.0, -(TIM_VAR + list));
}
void out_sampst(FILE *unit, int lowvar, int highvar)
{
/* Write sampst statistics for variables lowvar through highvar on file
"unit". */
int ivar, iatrr;
if(lowvar>highvar || lowvar > MAX_SVAR || highvar > MAX_SVAR) return;
fprintf(unit, "\n sampst Number");
fprintf(unit, "\nvariable of");
fprintf(unit, "\n number Average values Maximum");
fprintf(unit, " Minimum");
fprintf(unit, "\n___________________________________");
fprintf(unit, "_____________________________________");
for(ivar = lowvar; ivar <= highvar; ++ivar) {
fprintf(unit, "\n\n%5d", ivar);
sampst(0.00, -ivar);
for(iatrr = 1; iatrr <= 4; ++iatrr) pprint_out(unit, iatrr);
}
fprintf(unit, "\n___________________________________");
fprintf(unit, "_____________________________________\n\n\n");
}
void out_timest(FILE *unit, int lowvar, int highvar)
{
/* Write timest statistics for variables lowvar through highvar on file
"unit". */
int ivar, iatrr;
if(lowvar > highvar || lowvar > TIM_VAR || highvar > TIM_VAR ) return;
fprintf(unit, "\n timest");
fprintf(unit, "\n variable Time");
fprintf(unit, "\n number average Maximum Minimum");
fprintf(unit, "\n________________________________________________________");
for(ivar = lowvar; ivar <= highvar; ++ivar) {
fprintf(unit, "\n\n%5d", ivar);
timest(0.00, -ivar);
for(iatrr = 1; iatrr <= 3; ++iatrr) pprint_out(unit, iatrr);
}
fprintf(unit, "\n________________________________________________________");
fprintf(unit, "\n\n\n");
}
void out_filest(FILE *unit, int lowlist, int highlist)
{
/* Write timest list-length statistics for lists lowlist through highlist on
file "unit". */
int list, iatrr;
if(lowlist > highlist || lowlist > MAX_LIST || highlist > MAX_LIST) return;
fprintf(unit, "\n File Time");
fprintf(unit, "\n number average Maximum Minimum");
fprintf(unit, "\n_______________________________________________________");
for(list = lowlist; list <= highlist; ++list) {
fprintf(unit, "\n\n%5d", list);
filest(list);
for(iatrr = 1; iatrr <= 3; ++iatrr) pprint_out(unit, iatrr);
}
fprintf(unit, "\n_______________________________________________________");
fprintf(unit, "\n\n\n");
}
void pprint_out(FILE *unit, int i) /* Write ith entry in transfer to file
"unit". */
{
if(transfer[i] == -1e30 || transfer[i] == 1e30)
fprintf(unit," %#15.6G ", 0.00);
else
fprintf(unit," %#15.6G ", transfer[i]);
}
float expon(float mean, int stream) /* Exponential variate generation
function. */
{
return -mean * log(lcgrand(stream));
}
int random_integer(float prob_distrib[], int stream) /* Discrete-variate
generation function. */
{
int i;
float u;
u = lcgrand(stream);
for (i = 1; u >= prob_distrib[i]; ++i)
;
return i;
}
float uniform(float a, float b, int stream) /* Uniform variate generation
function. */
{
return a + lcgrand(stream) * (b - a);
}
float erlang(int m, float mean, int stream) /* Erlang variate generation
function. */
{
int i;
float mean_exponential, sum;
mean_exponential = mean / m;
sum = 0.0;
for (i = 1; i <= m; ++i)
sum += expon(mean_exponential, stream);
return sum;
}
/* Prime modulus multiplicative linear congruential generator
Z[i] = (630360016 * Z[i-1]) (mod(pow(2,31) - 1)), based on Marse and
Roberts' portable FORTRAN random-number generator UNIRAN. Multiple
(100) streams are supported, with seeds spaced 100,000 apart.
Throughout, input argument "stream" must be an int giving the
desired stream number. The header file lcgrand.h must be included in
the calling program (#include "lcgrand.h") before using these
functions.
Usage: (Three functions)
1. To obtain the next U(0,1) random number from stream "stream,"
execute
u = lcgrand(stream);
where lcgrand is a float function. The float variable u will
contain the next random number.
2. To set the seed for stream "stream" to a desired value zset,
execute
lcgrandst(zset, stream);
where lcgrandst is a void function and zset must be a long set to
the desired seed, a number between 1 and 2147483646 (inclusive).
Default seeds for all 100 streams are given in the code.
3. To get the current (most recently used) integer in the sequence
being generated for stream "stream" into the long variable zget,
execute
zget = lcgrandgt(stream);
where lcgrandgt is a long function. */
/* Define the constants. */
#define MODLUS 2147483647
#define MULT1 24112
#define MULT2 26143
/* Set the default seeds for all 100 streams. */
static long zrng[] =
{ 1,
1973272912, 281629770, 20006270,1280689831,2096730329,1933576050,
913566091, 246780520,1363774876, 604901985,1511192140,1259851944,
824064364, 150493284, 242708531, 75253171,1964472944,1202299975,
233217322,1911216000, 726370533, 403498145, 993232223,1103205531,
762430696,1922803170,1385516923, 76271663, 413682397, 726466604,
336157058,1432650381,1120463904, 595778810, 877722890,1046574445,
68911991,2088367019, 748545416, 622401386,2122378830, 640690903,
1774806513,2132545692,2079249579, 78130110, 852776735,1187867272,
1351423507,1645973084,1997049139, 922510944,2045512870, 898585771,
243649545,1004818771, 773686062, 403188473, 372279877,1901633463,
498067494,2087759558, 493157915, 597104727,1530940798,1814496276,
536444882,1663153658, 855503735, 67784357,1432404475, 619691088,
119025595, 880802310, 176192644,1116780070, 277854671,1366580350,
1142483975,2026948561,1053920743, 786262391,1792203830,1494667770,
1923011392,1433700034,1244184613,1147297105, 539712780,1545929719,
190641742,1645390429, 264907697, 620389253,1502074852, 927711160,
364849192,2049576050, 638580085, 547070247 };
/* Generate the next random number. */
float lcgrand(int stream)
{
long zi, lowprd, hi31;
zi = zrng[stream];
lowprd = (zi & 65535) * MULT1;
hi31 = (zi >> 16) * MULT1 + (lowprd >> 16);
zi = ((lowprd & 65535) - MODLUS) +
((hi31 & 32767) << 16) + (hi31 >> 15);
if (zi < 0) zi += MODLUS;
lowprd = (zi & 65535) * MULT2;
hi31 = (zi >> 16) * MULT2 + (lowprd >> 16);
zi = ((lowprd & 65535) - MODLUS) +
((hi31 & 32767) << 16) + (hi31 >> 15);
if (zi < 0) zi += MODLUS;
zrng[stream] = zi;
return (zi >> 7 | 1) / 16777216.0;
}
void lcgrandst (long zset, int stream) /* Set the current zrng for stream
"stream" to zset. */
{
zrng[stream] = zset;
}
long lcgrandgt (int stream) /* Return the current zrng for stream "stream". */
{
return zrng[stream];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -