This is the C source code for a function change_lengths (change) that changes the average interval length by the value given in change.
/*************************************/
/***** change_lengths (change) *****/
/*************************************/
/*
Changes the average length of the intervals by the
value given in "change". The interval starpoints
are stored in ts[0..N-1] and the corresponding
endpoints in te[0..N-1].
The function randomly picks an interval and adds
or subtracts chronons in order to achieve the new
average length.
*/
void change_lengths (int change) {
/*
Global variables or macros:
---------------------------
N = total number of intervals
ts[0..N-1] = intervals startpoints
te[0..N-1] = intervals endpoints
tmax = maximum value for a ts[] or a te[]
MAX_IDLE = max. number of loop runs that can be idle
total_length = sum of all intervals' lengths
average_length = current average length of the intervals
Local variables:
----------------
i = index of interval whose length will be changed
useless = counter for the number of intervals with ts >= te
idle = number of subsequent idle loop passes
difference = interval i's length = te[i] - ts[i]
direction = +1 if average length is to be increased
= -1 if average length is to be decreased
to_change = number of chronons that remain to be
added or subtracted
abs_change = abs(change) = change * direction
end = 0 if ts[i] is to be moved to the left or right
= 1 if te[i] is to be moved to the left or right
*/
unsigned i, useless, idle, difference, abs_change;
int end = 1;
long to_change;
short direction;
/* Are chronons added or subtracted */
if (change >= 0)
direction = 1;
else
direction = -1;
/* determine the absolute value of "change" */
abs_change = change * direction;
/* total amount of chronons to add / to substract */
to_change = change * N;
/* determine new total length */
total_length = total_length + to_change;
/* initialise random generator */
srand(seed);
/* initialise "idle" */
idle = 0;
/* main loop that subsequently adds or substracts chronons */
while ((to_change > 0) && (idle < MAX_IDLE)) {
/* find a suitable interval */
do {
i = rand() % N;
} while ((ts[i]==0) && (te[i]==tmax));
/* will start- or endpoint be changed? */
end = rand() % 2;
/* increase lengths */
if (direction == 1) {
idle++;
if ((end == 0) && (ts[i] > 0)) {
ts[i]--;
to_change--;
idle = 0;
}
if ((end == 1) && (te[i] < tmax)) {
te[i]++;
to_change--;
idle = 0;
}
}
/* decrease lengths */
else {
/* search for another interval if the current one
comprises no chronon, i.e. it is a timepoint.
The search is stopped when the number of useless
intervals matches the total number of intervals. */
useless = 0;
while ((ts[i] == te[i]) && (useless < N)) {
i = (i+1) % N;
useless++;
}
/* If no suitable interval is found then leave the loop */
if (useless >= N)
idle = MAX_IDLE;
/* If the interval i is suitable then ... */
if (ts[i] < te[i]) {
difference = te[i] - ts[i];
/* decrease length as much as possible */
if (difference <= abs_change) {
if (end)
te[i] = ts[i];
else
ts[i] = te[i];
to_change = to_change + difference;
}
else if ((difference > abs_change) &&
(to_change < (2*change)) ) {
if (!end)
ts[i] = ts[i] + abs_change;
else
te[i] = te[i] - abs_change;
to_change = to_change + abs_change;
}
else {
if (!end)
ts[i]++;
else
te[i]--;
to_change++;
}
}
}
}
if (to_change != 0) {
fprintf(stderr,"--- Warning ---\n");
fprintf(stderr,"Too many idle attempts!\n");
fprintf(stderr,"Abandoned change loop.\n");
total_length = total_length - to_change;
}
/* determine new average length */
average_length = total_length / N;
return;
}