Simultaneity

[From Richard Thurman (940414.1500)]

Bill Powers (940413.1430 MDT)

In Wolfgang Zocher's "Simcon" program written for use by CSGnetters
and largely ignored (and which makes an analogue computer out of a
digital computer), pains were taken to make sure that all functions
operated effectively simultaneously. This was done by establishing
two output variables for each function: an "old" variable and a
"new" variable. On each iteration, the "old" values of output from
the various functions are used as inputs to whatever succeeding
functions they are inputs to. This results in computing "new" values
for all the functions. Then, before the next iteration, all the
"new" values are copied into the corresponding "old" values.

To make this scheme approximate true parallel operation as in a real
analog computer, it is necessary to use a very small value of dt for
the inter-iteration time. The reason is that effects propagate only
from the input of each function to the output of the same function
in one iteration. If the loop contains 5 functions (but no transport
lags), 5 iterations are needed for a perturbation to propagate all
the way around the loop. The value of dt must be small enough so
that total loop transit time is negligible.

True transport lags are taken care of by a delay function in which
inputs are shifted through a shift register of the desired length
(in units of dt), one shift per iteration.

Bill, I'm having trouble thinking through how to write code for the
above. Do you have an example in "C" (or Pascal, Basic, etc.) that
you could pass along.

This really needs to be incorporated into your Primer Series. It
seems to be a very important point that would keep a lot of daring
fools (such as me) from trouble when their simulations start giving
unexplainable output. But even more important, it could keep us
from giving incorrect explanations when we do see ordinary output.

Rich

···

--------------------------------------------------
Richard Thurman
Air Force Armstrong Lab
6001 S. Power Rd. BLDG. 558
Mesa AZ. 85206-0904

(602) 988-6561
Thurman@hrlban1.aircrew.asu.edu
---------------------------------------------------

[From Richard Thurman (940418.1600)]

Bill Powers (940415.0705 MDT)

Thanks for the info on making digital computers play the analog game
correctly.

The computational trick in achieving simultaneity is quite simple.
... [stuff deleted]
The "old" output values are the values at the end of the previous
iteration. From them, "new" values are computed for the end of the
iteration. Then both new values become the old values for the start
of the next iteration. I suppose that for that last function in the
chain you don't need new and old values, but this is general.

Ok, I think I get what you were saying. Now, could you please look
over the following program and tell me if this is what you meant. I
want to make sure I got this concept down before I lose the idea.
Actually, you don't have to make comments. A simple "yep...thats it"
will do. Its a remake of your first program in the Primer Series.
If its correct I plan on stapling it (along with your previous
comments on simultaneity) to the back of the Primer Series. (At
least I want it for future reference!)

/* -------------------------------------------------------------- */
/* Simultaneity program in C: */
/* The disturbance is at zero for 12 iterations. */
/* Then it jumps to 10.0 for 13 iterations. */
#include "stdio.h"
void main()
{
float qd = 0.0,qi = 0.0,sp = 0.0,se = 0.0,sr = 20.0,qo = 0.0;
float qdOld = 0.0,spOld = 0.0,seOld = 0.0,qoOld = 0.0,qiOld = 0.0;
float kd = 1.0,ki = 1.0,ko = 8.0, kf = 1.0, dt = 0.1;
int i;
printf("\n");
for(i=0;i<25;++i)
{
if(i > 12) qd = 10.0; else qd = 0.0;
qi = kf*qoOld + kd*qdOld;
sp = ki*qiOld;
se = sr - spOld;
qo = qoOld + ko*seOld*dt;
qdOld = qd;
qiOld = qi;
spOld = sp;
seOld = se;
qoOld = qo;
printf(
"\x0d\x0a qd=%6.2f qi=%6.2f qo=%6.2f sp=%6.2f sr=%6.2f se=%6.2f",
qd,qi,qo,sp,sr,se);
}
(void) getch(); /* pause to view; press key to exit */
}
/* -------------------------------------------------------------- */

Another way to do this in a long chain is to compute backward, from
output to input. This way each function is using the inputs as they
are at the beginning of the iteration. However, when there are
several loops it can be hard to figure out the right order.

Yes that is the way I had been doing the computations. This seemed
to be the way to do it based upon the "Introduction to Modern
Psychology" textbook. I beleive it was chapter 4 (don't have it
handy to refer to) that said to compute through the loop backwards.
But it didn't give a very good explanation why. Well... the
explanation might have been good and my reading of it may have been
a bit off. At any rate I'm glad to have a little better handle on it.

We're not talking about large differences in results here (I think).
But you can see that simply doing computations in the normal forward
direction isn't, strictly speaking, correct. The old-new method is
simple enough that it should be tried first, to see if it makes any
difference. Once you've satisfied yourself that it doesn't, you can
go back to the shorter method with confidence.

I do worry about how to explain it to others though. On several
ocassions when I have tried to explain the basic concepts of PCT to
cognitive psychologists, I have gotten a lot of 'yes buts' and 'thats
just the same as' comments. I hope now that most of those protests
can be avoided if I can explain the cannonical PCT diagram (which
unfortunately looks sequential) and at the same time show code that
takes simultaneous computations into account.

Rich

···

--------------------------------------------------
Richard Thurman
Air Force Armstrong Lab
6001 S. Power Rd. BLDG. 558
Mesa AZ. 85206-0904

(602) 988-6561
Thurman@hrlban1.aircrew.asu.edu
---------------------------------------------------