Weight-transpose control model

[from Tracy B. Harms (2008-10-14 15:40 Pacific)]

re. Bill Powers (2008.10.13.1502 MDT)

...

{ CONTROL LOOPS IMPLEMENTED AS (SQUARE) MATRIX OPERATIONS}
procedure controlloops;
begin
MV(inputCoeffs,qi, p); { p = coeffs*qi}
VS(r,p,e); { e = r - p}
VI(e,o,ko); { o = o + ko * integral(e) * dt}
MV(w,o,temp); { temp = w * o}
VA(temp, d, qi); { qi = temp + d}
end;

I'm going to attempt to make some true statements about the way
controlloops is used. These may be basic and obvious but if I've
missed something here correction is vital.

When controlloops is called, six things have been established prior to
the call that are effectively constants for purposes of this function:

coeffs (a matrix) represents the current perceived situation, a.k.a.
the input weighting
w (a matrix) the output weighting
r (a vector)
ko (a scalar)
dt (a scalar, not passed as a parameter)
d (a vector)

Two things are relied on for existing values, then have their values changed:
o (a vector) is the list of control-system outputs
qi (a vector)

The five things that don't have descriptions are ones for which I
don't have a concept or explanation. Also, I don't understand how to
interpret "integral(e)" and the notes in which it occurs. (I have no
problem following the code, e.g. how it draws on the respective
element of e for each element of o, but I don't know why that counts
as an integral nor why that should be so applied in caclulating the
new overall output.)

I should also check that I am correct in understanding input and
output weights as being the relative ease of altering the respective
effects. A higher input weight means that a smaller change in the
environmental factors is required to produce a given quantity of input
effect, and a higher output weight means that a smaller change in
action is required to accomplish a given quantity of output effect.
Did I get that right?

Thank you,

Tracy

[From Bill Powers (2008.10.l4. 1943 MDT)]

Tracy B. Harms (2008-10-14 15:40 Pacific) –

re. Bill Powers (2008.10.13.1502
MDT)

{ CONTROL LOOPS IMPLEMENTED AS (SQUARE) MATRIX OPERATIONS}

procedure controlloops;

begin

MV(inputCoeffs,qi, p); { p = coeffs*qi}

VS(r,p,e);
{ e = r - p}

VI(e,o,ko);
{ o = o + ko * integral(e) * dt}

MV(w,o,temp);
{ temp = w * o}

VA(temp, d,
qi); { qi = temp +
d}

end;

I’m going to attempt to make some true statements about the way

controlloops is used. These may be basic and obvious but if I’ve

missed something here correction is vital.

When controlloops is called, six
things have been established prior to

the call that are effectively constants for purposes of this
function:

coeffs (a matrix) represents the current perceived situation,
a.k.a.

the input weighting

w (a matrix) the output weighting

r (a vector)

ko (a scalar)

dt (a scalar, not passed as a parameter)

d (a vector)

This is correct. Think of the basic PCT diagram as you read
this.
First we compute p, the vector of perceptual signals (one for each
control system). For the ith column of the matrix “coeffs”,
there are “maxmatrix” weights (the elements of the column). The
value of p[i] is sum of [ the weights coeffs[i,j] times the corresponding
environmental input variable, called qi[j].
__{v2 = M*v1 premultiply vector by square matrix}
procedure MV(var M:coefftype; var v1, v2: vectortype);
var i,j: integer;
begin
for i := 1 to maxmatrix do
begin
v2[i] := 0.0;
for j := 1 to maxmatrix do
v2[i] := v2[i] + M[i,j]*v1[j]
end;
end;__The perceptual signal is v1 and the input quantity is v2.

For the ith control system, we set the perceptual signal p[i] to zero,
and then accumulate the sum of (weight)*(qi[i]) over all the weights and
all the input quantities qi. The weight is the jth entry in the ith
column of the matrix called M in the function.

The matrix is square; there are maxmatrix control systems and maxmatrix
input weights per control system.

Next we compute the error vector: e[i] := r[i] - p[i], where r is a
vector of fixed reference signals and e is a vector of error signals.
This is done for each control system.

I don’t understand how
tointerpret “integral(e)” and the notes in which it occurs. (I
have noproblem following the code, e.g. how it draws on the respective
element of e for each element of o, but I don’t know why that counts as
an integral nor why that should be so applied in calulating the

new overall output.)

Now we get to the integral output function. Look at the definition of VI,
the vector integrating function. This accumulates the value of
“a” not over a set of input values, but over time: on each
iteration of the whole program, this function is performed once and adds
some amount to the value of b. You will notice that b is is not
initialized to zero in this function. Compare with the previous function,
in which v2[i] was set to zero before accumulating the weighted sum over
all values of j.

procedure VI(var a,b: vectortype; k: double);

var i: integer;

begin

for i := 1 to maxmatrix do

b[i] := b[i] + k*a[i]*dt;

end;

Looking at the call of this function, you’ll see that a is the error
signal and b is the output o. For each control system, the error signal
is multiplied by ko, the output gain (which is the same for all systems
in this program) and added to the previous value of the output o to
produce the next value of that output.

I should also check that I am
correct in understanding input and

output weights as being the relative ease of altering the respective

effects.

Not quite. On the input side, the weights in one column of the input
matrix “coeffs” tell how much each input quantity contributes
to the total perceptual signal. On the output side, in the “w”
matrix, the weights in one column tell how much one output contributes to
the value of each input quantity. Note that creating the transpose during
initialization makes w[j,i] = coeffs[i,j] – the indices are
interchanged. The state of one input quantity is the weighted sum of
effects from all the control system outputs.

A higher input weight
means that a smaller change in the

environmental factors is required to produce a given quantity of
input

effect, and a higher output weight means that a smaller change in

action is required to accomplish a given quantity of output effect.

Did I get that right?

Well yes, but backward. A higher input weight says that a given value of
input quantity (a variable in the environment) has more effect on the
perceptual signal; a higher output weight says that a given amount of
output, o, has a greater effect on one of the input quantities. Think of
the weights as little amplifiers with adjustable gains between -100 and
100 stuck into the connecting lines. I didn’t choose the gains very
wisely, but they work.

The output weights are used to add up the effects of all outputs on each
input quantity. I used a “temp” variable to allow using the
vector addition function again to add in a disturbance – and then
decided not to use any disturbance. You’ll see that the disturbance
vector is initialized to zero. That was so I could come back later and
use a nonzero disturbance if I wanted, which I didn’t.

Borland is now supplying a new version of Delphi called Turbo Delphi,
have to register to activate it for a free trial, but the trial period is
99 years. If you want to try it, I will send you the full source code
(which has several files in addition to the one I will send tomorrow) and
give cookbook instructions for compiling and running the program. In any
event I’ll include the executable code (for PCs) renamed to be a .txt
file to fool a dumb enough server.

By the way, I’d forgotten that this program lets you change the number of
control systems to any multiple of 5 from 5 to 500. This was written
quite a while ago, 5 or 10 years.

If I’m going in directions that don’t interest you just say so. I’m doing
this in between packing to move from my apartment to a double-wide mobile

Best,

Bill P.

[from Tracy B. Harms (2008-10-15 08:37 Pacific)]

Bill,

So, I don't think I'll have much need for the remaining code. You can
save your effort on that, as things stand. It looks like this is the
core of the program and everything else will be specific to collecting
settings, generating randomized values, and reporting output.

At this point I wish to check that the main output, for report or
display to the user, is the series of qi vectors that result from each
pass. These are the perceived values for the list of systems.

The incidental output is the modification to o

No other values computed within controlloops matter outside the current pass.

If those statements are true, you've gotten your ideas across.

understanding of this whole model now. It will be fun to implement it.

Tracy

···

On Tue, Oct 14, 2008 at 8:01 PM, Bill Powers <powers_w@frontier.net> wrote:

[From Bill Powers (2008.10.l4. 1943 MDT)]

...

[From Bill Powers (2008.10.15.0943 MDT)]

Tracy B. Harms (2008-10-15 08:37 Pacific) --

At this point I wish to check that the main output, for report or
display to the user, is the series of qi vectors that result from each
pass. These are the perceived values for the list of systems.

Actually, four of the variables are plotted: input quantity (qi),
perceptual signal (p), reference signal (r), and output (o).

Because the perceptual signals in each system depend on ALL of the
environmental variables, and the actions of ALL the systems affect
each qi, an external observer could not tell what is being
controlled. Yet each system eventually gets its own perceptual signal
close to its given reference signal.

The reference signal values are initially random. You can select a
sine-wave or a cosine-wave pattern at any time, which also restarts
the program with a new set of random input weights (the output matrix
is automatically initialized to be the transpose of the matrix of
input weights). Sometimes the control systems are able to correct
their errors relatively quickly; other times, the convergence takes a
very long time. The difference is in the degree of orthogonality of
the different sets of input weights, which determines how close the
systems are to a state of conflict.

I'm attaching the executable file with the extension changed from
.exe to .txt. If that gets through, rename it to .exe to run it. If
it doesn't, I'll zip the file and try it that way. It will probably
help to see how this collection of systems behaves.

Best,

Bill P.

MultiControl.txt (405 KB)

[from Tracy B. Harms (2008-10-15 09:23 Pacific)]
Bill.

I'm trying to reconcile "random" with "sine-wave or cosine-wave
pattern". Are these three different options for establishing reference
levels?

Do the wave patterns you mention here indicate changing reference
levels over time, or are you talking about a wave across the vector of
system references?

Tracy

···

On Wed, Oct 15, 2008 at 9:00 AM, Bill Powers <powers_w@frontier.net> (2008.10.15.0943 MDT) wrote:

...
The reference signal values are initially random. You can select a sine-wave
or a cosine-wave pattern at any time, which also restarts the program with a
new set of random input weights (the output matrix is automatically
initialized to be the transpose of the matrix of input weights).

[From Bill Powers (2008.10.15.1033 MDT)]

Tracy B. Harms (2008-10-15 09:23 Pacific) --

I'm trying to reconcile "random" with "sine-wave or cosine-wave

pattern". Are these three different options for establishing reference
levels?

Yes. The point is to show that each system can bring its own perceptual signal close to an arbitrarily-set reference value. The initial reference values (on startup) are set at random. After that you can pick a sine or a cosine pattern. I chose these patterns because they're easy to generate. I had a third choice, which generated a new random pattern of reference signals, but that just looks like a big mess and it's hard to see the convergence.

Do the wave patterns you mention here indicate changing reference
levels over time, or are you talking about a wave across the vector of
system references?

The latter. There is no significance in the "wave" pattern; it's just a way of setting the different reference signals to different values. Also, it's easy to see the convergence of the pattern of perceptual signals to the same pattern as the reference signals.

The convergence to final values is slow most of the time, partly because I used a very conservative gain value factor behind the one you can adjust, and partly because there is no reorganization. The gain has to be set for the worst case which would be no conflict at all between systems. If there were no conflict, the loop gain would be very high, and if the master gain factor is set too high the system will blow up. Setting the master gain low enough to prevent blowup in the worst case results in very slow convergence most of the time.

If reorganization were added to this demo, convergence would become rapid enough that we could have all the reference signals varying while the perceptual signals tracked them.

Best,

Bill

[Martin Taylor 2008.10.15.13.12]

[From Bill Powers (2008.10.15.0943 MDT)]

I'm attaching the executable file with the extension changed from .exe to .txt. If that gets through, rename it to .exe to run it. If it doesn't, I'll zip the file and try it that way. It will probably help to see how this collection of systems behaves.

Worked for me, running a virtual PC (under VMWare Fision 2 under Mac OS X 10.5.4). I received it as a Mac, changed the extension to .exe , copied it into the virtual PC, and ran it with no problem.

It didn't work if I first copied it to the virtual PC and then changed the extension. Doing that, the PC still thought it was a text file even after changing the extension. Whether that happens on a real PC, I cannot guess, but everything else I have run on the virtual PC seems to be just as it would be in a real PC. If this is different, it would be nice to know.

Martin

[From Bill Powers (2008.10.15.1`131 MDT)]

Martin Taylor 2008.10.15.13.12 --

Thanks for the useful information, Martin. Renaming a file works under Windows, so I don't know why the virtualizer doesn't do it right.

I'll send a somewhat tweaked version of the program if anyone wants it -- it runs a little faster. I didn't really try to optimize anything since I was just checking out the "transpose" proposition and didn't think anyone else would be seeing the result when I wasn't there to explain things.

Best,

Bill

[Martin Taylor 2008.10.15.14.19]

[From Bill Powers (2008.10.15.1`131 MDT)]

Martin Taylor 2008.10.15.13.12 --

Thanks for the useful information, Martin. Renaming a file works under Windows, so I don't know why the virtualizer doesn't do it right.

In case it's relevant, my Windows is XP Professional with SP 2. I have a different virtualizer called Parallels, as well. I might try it there, or even on the Mac booted directly into Windows (i.e. not under Mac OS X).

Martin

So, each component of qi is an environmental variable, meaning that
each one correlates with something that could be measured directly and
independently for that particular aspect of the world by an objective
observer. (For this purpose, we'll ignore the fact that environmental
variables can occur in a way that precludes objective observation,
e.g. when they are features within a network of control systems.)

In contast with this, each component of p correlates with exactly one
of the control systems.

Square matrix coeffs is a constant that mediates between qi and p by
creating "baskets" (combined relative weightings) by which *all*
aspects of qi are significant to *each* part of p. Although there is
the temptation to imagine one-to-one correspondence between "things in
the world" (constituents of qi) and "things accomplished"
(constituents of p) the actual structure involves an all-to-all
relationship (and another such relationship for output effects).

I hadn't properly understood the difference between qi and p until I
went through the process of composing this message. Maybe I have it
now.

As for the overall excercise, it looks as though this is a way to
explore a simplified technique to network specification that depends
upon having the number of control systems and environmental factors be
equal. As for why you chose transposition to differentiate the two
weightings, I'd like to hear more. My guess is that it is because it
is conceptually simple and you wondered whether that's all it takes.
(And it turned out that it is.)

Tracy

···

On Wed, Oct 15, 2008 at 9:00 AM, Bill Powers <powers_w@frontier.net> wrote:

[From Bill Powers (2008.10.15.0943 MDT)]

Tracy B. Harms (2008-10-15 08:37 Pacific) --

At this point I wish to check that the main output, for report or
display to the user, is the series of qi vectors that result from each
pass. These are the perceived values for the list of systems.

Actually, four of the variables are plotted: input quantity (qi), perceptual
signal (p), reference signal (r), and output (o).

Because the perceptual signals in each system depend on ALL of the
environmental variables, and the actions of ALL the systems affect each qi,
an external observer could not tell what is being controlled. Yet each
system eventually gets its own perceptual signal close to its given
reference signal.

[From Bill Powers (2008.10.15.1655 MDT)]

So, each component of qi is an environmental variable, meaning that
each one correlates with something that could be measured directly and
independently for that particular aspect of the world by an objective
observer. (For this purpose, we'll ignore the fact that environmental
variables can occur in a way that precludes objective observation,
e.g. when they are features within a network of control systems.)

Yes. I probably should have used a different notation, but as mentioned I was writing for myself and I knew what I meant.

Suppose we just refer to variables in the environment as v[i]. Any of them could be measured by a physicist who happened to be passing by. This would avoid the confusion of the notation "qi" which is usually taken to mean the external counterpart of the internal perceptual signal. As you note, under that meaning, qi does not necessarily have any physical signficance since it is created from multiple inputs by the input function of the control system.

In the case of the weight-transpose model we have an extreme example of this situation, since each control system creates a different "virtual" qi by the weights it applies to sensed representations of ALL the environmental variables v[i]. None of the qi's thus created actually exists, in the sense that there is some single physical variable that corresponds to each perceptual signal. The implied model says that each v[i] has a magnitude which is reported by some kind of sensor, and that each sensor signal fans out to all the control systems where it enters each input function with a weight selected at random.

In contast with this, each component of p correlates with exactly one
of the control systems.

Yes.

Square matrix coeffs is a constant that mediates between qi and p by
creating "baskets" (combined relative weightings) by which *all*
aspects of qi are significant to *each* part of p.

Yes.

Although there is
the temptation to imagine one-to-one correspondence between "things in
the world" (constituents of qi) and "things accomplished"
(constituents of p) the actual structure involves an all-to-all
relationship (and another such relationship for output effects).

You got it. That's what I intended to create in this model. I admire your ability to see through my code to grasp what I had in mind.

As for the overall excercise, it looks as though this is a way to
explore a simplified technique to network specification that depends
upon having the number of control systems and environmental factors be
equal.

That's a special case. In general, the number of control systems could be greater than or less than the number of v[i]. If it's less (which I suspect is the actual case), then some v[i] (or some dimensions of the ensemble) could be disturbed without causing error in any control system, and those would simply change. If there are fewer v[i] than control systems, then conflict necessarily exists, since some variables would have to have two different values at the same time to satisfy all the control systems' possibly different reference conditions. In the case I chose, there is exactly one solution of the whole set of simultaneous equations, and the control systems find it, or come as close to doing so as possible.

As for why you chose transposition to differentiate the two
weightings, I'd like to hear more. My guess is that it is because it
is conceptually simple and you wondered whether that's all it takes.
(And it turned out that it is.)

Precisely. I started by tediously tracing out the signs of the output weights that would be required to keep the feedback negative for every possible path from input, through error, through output, and back to input (for each control system). Because of the way I happened to number the indices, it came out that each output weight had to have the same sign as the input weight in the loop, and the easiest way to achieve that is simply to let the output weight equal the corresponding input weight. Using a more conventional way of numbering the indices, this comes out to

w[j,i] = coeff[i,j]

which I vaguely recalled, and then verified, to be the "transpose" relationship. That made me happy, since I never really caught on to matrix algebra. I worked this out with the case of three v[i] and quickly generalized to any number (while wondering if that was legitimate). Hence the present model, to see if that really would work.

Have you been able to run the model yet?

Best,

Bill P.

···

At 03:44 PM 10/15/2008 -0700, Tracy Harms wrote:

[from Tracy B. Harms (2008-10-16 14:10 Pacific)]

re. Bill Powers (2008.10.15.1655 MDT)

...

Have you been able to run the model yet?

Best,

Bill P.

I have, and it is lots of fun. I'm having some problems getting it
set up on a Vista machine (where file types are harder to modify), but
the XP machine I use runs it fine.

At the moment my biggest curiosity is regarding what the range of
values should be used in random population of the coefficient matrices
and the reference levels. My intuition is that they lie beteen
positive one and negative one. I see that the default starting value
for ko is 60, but the value (and meaning) of dt seems obscure.

At the obviously high risk of presenting code for which I have not
done any testing, here's my draft of J code that is equivalent to the
Pascal you posted to this thread earlier. The similarity between this
program and the comments within controlloops seems noteworthy.

ps=: vs (+/ . *) wci NB. perceived situation
oe=: oe + (ko*dt) * rs - ps NB. output effect (alters factors)
vs=: oe (+/ . *) wco NB. variable-factor situation
)

Best regards,

Tracy

···

On Wed, Oct 15, 2008 at 4:44 PM, Bill Powers <powers_w@frontier.net> wrote:

[From Bill Powers (2008.10.15.1655 MDT)]

At 03:44 PM 10/15/2008 -0700, Tracy Harms wrote:

So, each component of qi is an environmental variable, meaning that
each one correlates with something that could be measured directly and
independently for that particular aspect of the world by an objective
observer. (For this purpose, we'll ignore the fact that environmental
variables can occur in a way that precludes objective observation,
e.g. when they are features within a network of control systems.)

Yes. I probably should have used a different notation, but as mentioned I
was writing for myself and I knew what I meant.

Suppose we just refer to variables in the environment as v[i]. Any of them
could be measured by a physicist who happened to be passing by. This would
avoid the confusion of the notation "qi" which is usually taken to mean the
external counterpart of the internal perceptual signal. As you note, under
that meaning, qi does not necessarily have any physical signficance since it
is created from multiple inputs by the input function of the control system.

In the case of the weight-transpose model we have an extreme example of this
situation, since each control system creates a different "virtual" qi by the
weights it applies to sensed representations of ALL the environmental
variables v[i]. None of the qi's thus created actually exists, in the sense
that there is some single physical variable that corresponds to each
perceptual signal. The implied model says that each v[i] has a magnitude
which is reported by some kind of sensor, and that each sensor signal fans
out to all the control systems where it enters each input function with a
weight selected at random.

In contast with this, each component of p correlates with exactly one
of the control systems.

Yes.

Square matrix coeffs is a constant that mediates between qi and p by
creating "baskets" (combined relative weightings) by which *all*
aspects of qi are significant to *each* part of p.

Yes.

Although there is
the temptation to imagine one-to-one correspondence between "things in
the world" (constituents of qi) and "things accomplished"
(constituents of p) the actual structure involves an all-to-all
relationship (and another such relationship for output effects).

You got it. That's what I intended to create in this model. I admire your
ability to see through my code to grasp what I had in mind.

As for the overall excercise, it looks as though this is a way to
explore a simplified technique to network specification that depends
upon having the number of control systems and environmental factors be
equal.

That's a special case. In general, the number of control systems could be
greater than or less than the number of v[i]. If it's less (which I suspect
is the actual case), then some v[i] (or some dimensions of the ensemble)
could be disturbed without causing error in any control system, and those
would simply change. If there are fewer v[i] than control systems, then
conflict necessarily exists, since some variables would have to have two
different values at the same time to satisfy all the control systems'
possibly different reference conditions. In the case I chose, there is
exactly one solution of the whole set of simultaneous equations, and the
control systems find it, or come as close to doing so as possible.

[From Bruce Abbott (2008.10.16.1810 EDT)]

Tracy B. Harms (2008-10-16 14:10 Pacific) --

At the moment my biggest curiosity is regarding what the range of
values should be used in random population of the coefficient matrices
and the reference levels. My intuition is that they lie beteen
positive one and negative one. I see that the default starting value
for ko is 60, but the value (and meaning) of dt seems obscure.

Excuse me for intruding, but as Bill P. seems to be occupied at the moment,
I thought I'd step in as I know the answer to this one.

dt is the size of the increment in time with each iteration of the loop,
typically 1/60th second in Bill's programs.

Bruce A.

[From David M. Goldstein 92008.10.16.2100 EDT0]

Re.: Tracy B. Harms (2008-10-16 14:10 Pacific)]

Can you explain how to run your program in J?

Thanks,

David

···

----- Original Message ----
From: Tracy Harms kaleidic@GMAIL.COM
To: CSGNET@LISTSERV.ILLINOIS.EDU
Sent: Thursday, October 16, 2008 5:15:15 PM
Subject: Re: Weight-transpose control model

[from Tracy B. Harms (2008-10-16 14:10 Pacific)]

re. Bill Powers (2008.10.15.1655 MDT)

Have you been able to run the model yet?

Best,

Bill P.

I have, and it is lots of fun. I’m having some problems getting it
set up on a Vista machine (where file types are harder to modify), but
the XP machine I use runs it fine.

At the moment my biggest curiosity is regarding what the range of
values should be used in random population of the coefficient matrices
and the reference levels. My intuition is that they lie beteen
positive one and negative one. I see that the
default starting value
for ko is 60, but the value (and meaning) of dt seems obscure.

At the obviously high risk of presenting code for which I have not
done any testing, here’s my draft of J code that is equivalent to the
Pascal you posted to this thread earlier. The similarity between this
program and the comments within controlloops seems noteworthy.

ps=: vs (+/ . ) wci NB. perceived situation
oe=: oe + (ko
dt) * rs - ps NB. output effect (alters factors)
vs=: oe (+/ . *) wco NB. variable-factor situation
)

Best regards,

Tracy

On Wed, Oct 15, 2008 at 4:44 PM, Bill Powers powers_w@frontier.net wrote:

[From Bill Powers
(2008.10.15.1655 MDT)]

At 03:44 PM 10/15/2008 -0700, Tracy Harms wrote:

So, each component of qi is an environmental variable, meaning that
each one correlates with something that could be measured directly and
independently for that particular aspect of the world by an objective
observer. (For this purpose, we’ll ignore the fact that environmental
variables can occur in a way that precludes objective observation,
e.g. when they are features within a network of control systems.)

Yes. I probably should have used a different notation, but as mentioned I
was writing for myself and I knew what I meant.

Suppose we just refer to variables in the environment as v[i]. Any of them
could be measured by a physicist who happened to be passing by. This would
avoid the confusion of the notation “qi” which is
usually taken to mean the
external counterpart of the internal perceptual signal. As you note, under
that meaning, qi does not necessarily have any physical signficance since it
is created from multiple inputs by the input function of the control system.

In the case of the weight-transpose model we have an extreme example of this
situation, since each control system creates a different “virtual” qi by the
weights it applies to sensed representations of ALL the environmental
variables v[i]. None of the qi’s thus created actually exists, in the sense
that there is some single physical variable that corresponds to each
perceptual signal. The implied model says that each v[i] has a magnitude
which is reported by some kind of sensor, and that each sensor signal fans
out to all the control systems where it enters each input function with a
weight selected
at random.

In contast with this, each component of p correlates with exactly one
of the control systems.

Yes.

Square matrix coeffs is a constant that mediates between qi and p by
creating “baskets” (combined relative weightings) by which all
aspects of qi are significant to each part of p.

Yes.

Although there is
the temptation to imagine one-to-one correspondence between “things in
the world” (constituents of qi) and “things accomplished”
(constituents of p) the actual structure involves an all-to-all
relationship (and another such relationship for output effects).

You got it. That’s what I intended to create in this model. I admire your
ability to see through my code to grasp what I had in mind.

As for the overall excercise,
it looks as though this is a way to

explore a simplified technique to network specification that depends
upon having the number of control systems and environmental factors be
equal.

That’s a special case. In general, the number of control systems could be
greater than or less than the number of v[i]. If it’s less (which I suspect
is the actual case), then some v[i] (or some dimensions of the ensemble)
could be disturbed without causing error in any control system, and those
would simply change. If there are fewer v[i] than control systems, then
conflict necessarily exists, since some variables would have to have two
different values at the same time to satisfy all the control systems’
possibly different reference conditions. In the case I chose, there is
exactly one solution of the whole set of simultaneous equations, and the

control systems find it, or come as close to doing so as possible.

Hi, David.

I've attached my script, and also included the code in this message.
After saving it to your system as a .ijs file, use the J console to
execute a call such as the following (with appropriate file path,
etc.)

Having done so, you will have various values defined as a result, such
as rs (the randomly assigned reference signal vector). You can test
that by putting in a name, such as here:

rs
_0.310593 0.185112 0.694556 0.92416 _0.975163

Execution of one pass is done by calling act with any parameter, which
it ignores. (In the example shown here I've passed a one.) For
testing, I just run it again and again manually and look at the
numbers that result, like so:

act 1
_0.422742 _0.192465 0.853753 0.986422 _0.268204
0.112149 0.377578 _0.159197 _0.0622626 _0.706959
_0.253645 _0.115479 0.512252 0.591853 _0.160922
_0.0526892 _0.0562787 _0.356158 _0.188647 _0.0352721
act 1
_0.299002 0.147799 0.376033 0.835927 _0.915013
_0.0115908 0.0373132 0.318523 0.088233 _0.0601501
_0.433046 _0.0267997 0.737872 1.09341 _0.70993
_0.0899558 _0.0130608 _0.513027 _0.348514 _0.155608
act 1
_0.290804 0.176453 0.23574 0.761155 _0.709803
_0.0197889 0.00865943 0.458816 0.163005 _0.26536
_0.607529 0.079072 0.879316 1.5501 _1.13581
_0.126201 0.0385357 _0.61137 _0.49408 _0.248956

Each pass produces four lines. The first reports the error, the
difference between the reference and the perception. Next are the
perceived state, the output effect, and the external situation.

I've not confirmed that this fits Bill's model, but I didn't want to
delay any longer on your request. It still looks like it has a
tendency to "blow up", with errors and output driving to infinity. But
it may be close.

Obviously the interface niceties are still to be constructed.

Have fun,

Tracy

wtpmtm.ijs (867 Bytes)

···

On Thu, Oct 16, 2008 at 6:04 PM, D GOLDSTEIN <davidmg@verizon.net> wrote:

[From David M. Goldstein 92008.10.16.2100 EDT0]

Re.: Tracy B. Harms (2008-10-16 14:10 Pacific)]

Can you explain how to run your program in J?

Thanks,
David

______________________________________________________________________
NB. William T. Powers' matrix-transpose model
NB. translated to J by Tracy Harms (EARLY DRAFT, 2008-10-17)
NB. wtpmtm.ijs

size=: 5 NB. count of control systems in
this network
wco=: |: wci=: 1-~2* ? 0 \$~ 2# size NB. weighting coefficients,
input and output
ko=: 60
dt=: 0.01
ps=: size # 0
oe=: size # 0
vs=: 1-~2* ? size # 0
rs=: 1-~2* ? size # 0

act=: verb define
ps=: vs (+/"_1 . *) wci NB. perceived situation
oe=: oe + (ko*dt) * rs - ps NB. output effect (alters factors)
vs=: oe (+/"_1 . *) wco NB. variable-factor situation
(rs-ps),ps,oe,:vs NB. output for display during testing
)

Content-Type: application/octet-stream; name=wtpmtm.ijs
X-Attachment-Id: f_fmf5tato0

from [David Goldstein (2008.10.17.1606 EDT)]

Thanks Tracy, I'll give it a try in the near future.
My only reaction so far is that it shouldn't 'blow up' if it were a negative feedback control system.
I am a novice at this, and appreciate your help.
David

···

----- Original Message ----- From: "Tracy Harms" <kaleidic@GMAIL.COM>
To: <CSGNET@LISTSERV.ILLINOIS.EDU>
Sent: Friday, October 17, 2008 2:45 PM
Subject: Re: Weight-transpose control model

On Thu, Oct 16, 2008 at 6:04 PM, D GOLDSTEIN <davidmg@verizon.net> wrote:

[From David M. Goldstein 92008.10.16.2100 EDT0]

Re.: Tracy B. Harms (2008-10-16 14:10 Pacific)]

Can you explain how to run your program in J?

Thanks,
David

Hi, David.

I've attached my script, and also included the code in this message.
After saving it to your system as a .ijs file, use the J console to
execute a call such as the following (with appropriate file path,
etc.)

Having done so, you will have various values defined as a result, such
as rs (the randomly assigned reference signal vector). You can test
that by putting in a name, such as here:

rs
_0.310593 0.185112 0.694556 0.92416 _0.975163

Execution of one pass is done by calling act with any parameter, which
it ignores. (In the example shown here I've passed a one.) For
testing, I just run it again and again manually and look at the
numbers that result, like so:

act 1
_0.422742 _0.192465 0.853753 0.986422 _0.268204
0.112149 0.377578 _0.159197 _0.0622626 _0.706959
_0.253645 _0.115479 0.512252 0.591853 _0.160922
_0.0526892 _0.0562787 _0.356158 _0.188647 _0.0352721
act 1
_0.299002 0.147799 0.376033 0.835927 _0.915013
_0.0115908 0.0373132 0.318523 0.088233 _0.0601501
_0.433046 _0.0267997 0.737872 1.09341 _0.70993
_0.0899558 _0.0130608 _0.513027 _0.348514 _0.155608
act 1
_0.290804 0.176453 0.23574 0.761155 _0.709803
_0.0197889 0.00865943 0.458816 0.163005 _0.26536
_0.607529 0.079072 0.879316 1.5501 _1.13581
_0.126201 0.0385357 _0.61137 _0.49408 _0.248956

Each pass produces four lines. The first reports the error, the
difference between the reference and the perception. Next are the
perceived state, the output effect, and the external situation.

I've not confirmed that this fits Bill's model, but I didn't want to
delay any longer on your request. It still looks like it has a
tendency to "blow up", with errors and output driving to infinity. But
it may be close.

Obviously the interface niceties are still to be constructed.

Have fun,

Tracy

______________________________________________________________________
NB. William T. Powers' matrix-transpose model
NB. translated to J by Tracy Harms (EARLY DRAFT, 2008-10-17)
NB. wtpmtm.ijs

size=: 5 NB. count of control systems in
this network
wco=: |: wci=: 1-~2* ? 0 \$~ 2# size NB. weighting coefficients,
input and output
ko=: 60
dt=: 0.01
ps=: size # 0
oe=: size # 0
vs=: 1-~2* ? size # 0
rs=: 1-~2* ? size # 0

act=: verb define
ps=: vs (+/"_1 . *) wci NB. perceived situation
oe=: oe + (ko*dt) * rs - ps NB. output effect (alters factors)
vs=: oe (+/"_1 . *) wco NB. variable-factor situation
(rs-ps),ps,oe,:vs NB. output for display during testing
)

[From Rick Marken (2008.10.17.1320)]

David Goldstein (2008.10.17.1606 EDT)--

Thanks Tracy, I'll give it a try in the near future.
My only reaction so far is that it shouldn't 'blow up' if it were a negative
feedback control system.

Actually, even negative feedback systems can "blow up" if their gain
and slowing parameters aren't adjusted properly. The higher the gain
of a system the slower the response must be or the system will "blow"
(actually, it will be unstable, as in Parkinson's disease).

Best

Rick

···

--
Richard S. Marken PhD
rsmarken@gmail.com

[from Tracy B. Harms (2008-10-17 13:42 Pacific)]

I'd like to add that if you wish to reset to a newly generated set of
values, the easiest technique is to reload the file. If you want to
reset a single aspect, you can copy the appropriate initialization
line from the script and execute it in the console.

The entire J language was designed with calculator-style use of the
console as a centerpiece idea, so I definitely recommend playing
around somewhat to get a sense of its interactivity. My four-year old
son, Frederick, used the J console for the first time last night.
Together we explored + (addition), i. (integers), ' (literal character
lists), =. (naming), < (boxing), and # (counting).

Finally, since the recent conversation included a lot of emphasis on
"functional" or "applicative" programming, it is worth mentioning that
the function I've offered here is NOT in that category. It is all
about its "side-effects", i.e. it changes the things that it relies
upon for its calculation.

Tracy

[From Bill Powers (2008.10.18.0242 MDT)]

I've attached my script, and also included the code in this message.
After saving it to your system as a .ijs file, use the J console to
execute a call such as the following (with appropriate file path,
etc.)

Appended is a cleaned-up version of my program, with simplified
parameters. The gain parameter is no longer adjustable, and the
smallest number of control systems is 5. If you use the given values
of dt (0.0002) and ko (1.0), the systems will be stable for all
numbers of systems from 5 to 500. As usual, the executable program is
attached with its extension changed to .txt. Change it back to .exe
to run the program.

Every time you click on Sine or Cosine or change the number of
systems, a new matrix of random input weights is generated, and the
output matrix is set to the transpose of the input matrix. For some
matrices, convergence will be slow and the values of the outputs and
environmental variables will be very large. These are the matrices
whose determinants approach zero, indicating that no solution exists.
The chances of a truly unsolvable system are very close to zero (a
state of pure conflict). However, as that state is approached,
outputs oppose each other more and more, so if the control systems
have limits on the amount of output they can generate, control will
be lost for relatively mild degrees of conflict.

Note that many hundreds of iterations are needed to reach final
convergence, since each iteration represents only a small interval of
time. If you can make the J program loop some number of times each
time you initiate a calculation, you may get a better test of how the
program is working.

Note also that while the perceptual signals will approach the
reference signals, the outputs and environmental variables will not
show any orderly relationships. It occurs to me that this
demonstration may be the final disproof of the principle of
behaviorism, because the regularities in these collections of control
systems are not detectable through observing their behavior -- their outputs.

best,

Bill P.

MultiControlPrj.txt (404 KB)

···

At 11:45 AM 10/17/2008 -0700, Tracy Harms wrote:

==============================================================================
unit MultiControlUnit;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ComCtrls, Spin;

type
TMultiControl = class(TForm)
Panel1: TPanel;
SinePat: TButton;
CosinePat: TButton;
SetNumPts: TSpinEdit;
Label2: TLabel;
StartStop: TButton;
Button1: TButton;
Label1: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
procedure StartStopClick(Sender: TObject);
procedure SinePatClick(Sender: TObject);
procedure CosinePatClick(Sender: TObject);
procedure SetNumPtsChange(Sender: TObject);
procedure CreateMulti(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure idleloop(Sender: TObject; var Done: boolean);
end;

var
MultiControl: TMultiControl;

implementation

{\$R *.dfm}

const maxmax = 501;

type coefftype = array[1..maxmax, 1..maxmax] of double;
vectortype = array[1..maxmax] of double;

var qi, p, e, o, r: vectortype;
inputCoeffs,w: coefftype;
oldr, oldp, oldq, oldo: array[1..maxmax] of integer;
x, maxy, maxx, stage: integer;
dt,ko: double;
ersq: double;
niter,maxmatrix: integer;
pause: boolean;

{v2 = M*v1 premultiply vector by square matrix}
procedure MV(var M:coefftype; var v1, v2: vectortype);
var i,j: integer;
begin
for i := 1 to maxmatrix do
begin
v2[i] := 0.0;
for j := 1 to maxmatrix do
v2[i] := v2[i] + M[i,j]*v1[j]
end;
end;

{ C = A - B Vector subtract}
procedure VS(var A,B,C: vectortype);
var i: integer;
begin
for i := 1 to maxmatrix do
C[i] := A[i] - B[i];
end;

{ C = A + B vector add}
procedure VA(var A,B,C: vectortype);
var i: integer;
begin
for i := 1 to maxmatrix do
C[i] := A[i] + B[i];
end;

{B = k*int(A) vector integrate}
procedure VI(var a,b: vectortype; k: double);
var i: integer;
begin
for i := 1 to maxmatrix do
b[i] := b[i] + k*a[i]*dt;
end;

{ CONTROL LOOPS IMPLEMENTED AS (SQUARE) MATRIX OPERATIONS}
procedure controlloops;
begin
MV(inputCoeffs,qi, p); { p = coeffs*qi}
VS(r,p,e); { e = r - p}
VI(e,o,ko); { o = o + ko * integral(e) * dt}
MV(w,o,qi); { qi = w * o}
end;

{\$J+}
procedure showvariables;
var i,j,y: integer;
s: double;
begin
s := (maxx - 15)/(maxmatrix - 1); // SET X SCALE FOR PLOTTING
y := multicontrol.clientheight - round(ersq/2);
if niter >= 5000 div maxmatrix then
with multicontrol, canvas do
begin
font.color := clRed;
textout(10,clientheight-15,'RMS ERROR'); // REFRESH LEGEND
end;
if (niter mod 500) = 0 then // PLOT EVERY 500TH ITERATION
with multicontrol,canvas do
begin
color := clSilver;
pen.color := RGB(0,180,255);
font.Color := clRed;
ellipse(5+x - 2,y - 2,5+x + 2,y + 2);
x := x + 1;
if x >= clientwidth - 30 then x := 0;
if ((niter mod 15000) = 0) or (niter = 1) then
begin
fillrect(rect(x + 5,y,x + 105,y + 15));
textout(x+5,y - 14,floattostrf(ersq/5,fffixed,5,0));
end;
end;
if (niter mod 150) = 0 then
for i := 1 to maxmatrix do
with multicontrol,canvas do
begin
j := round(s*(i-1)) + 3;
pen.Color := clSilver;
brush.Color := clSilver;
ellipse(j-5,maxy div 2 - oldr[i] - 5,j+5,maxy div 2 - oldr[i] + 5);
ellipse(j-3,maxy div 2 - oldp[i] - 3,j+3,maxy div 2 - oldp[i] + 3);
ellipse(j-3,maxy div 2 - oldq[i] - 3,j+3,maxy div 2 - oldq[i] + 3);
ellipse(j-3,maxy div 2 - oldo[i] - 3,j+3,maxy div 2 - oldo[i] + 3);
oldr[i] := round(r[i] /5.0);
oldp[i] := round(p[i] /5.0);
oldq[i] := round(qi[i] /5.0);
oldo[i] := round(o[i]/5.0);
pen.color := clAqua;
brush.color := clAqua;
ellipse(j-5,maxy div 2 - oldr[i] - 5,j+5,maxy div 2 - oldr[i] + 5);
pen.color := RGB(250,0,0);
brush.color := RGB(250,0,0);
ellipse(j-3,maxy div 2 - oldp[i] - 3,j+3,maxy div 2 - oldp[i] + 3);
pen.Color := clYellow;
brush.color := clYellow;
ellipse(j-3,maxy div 2 - oldq[i] - 3,j+3,maxy div 2 - oldq[i] + 3);
pen.Color := clBlack;
brush.color := clBlack;
ellipse(j-3,maxy div 2 - oldo[i] - 3,j+3,maxy div 2 - oldo[i] + 3);
brush.Color := clSilver;
end;
end;

procedure initmatrix;
var i,j: integer;
sumsqr: double;
begin
sumsqr := 0.0;
for i := 1 to maxmatrix do
for j := 1 to maxmatrix do // LOAD RANDOM INPUT COEFFICIENTS, -1 TO 1
begin
inputCoeffs[i,j] := 1.98*(random - 0.5);
sumsqr := sumsqr + sqr(inputCoeffs[i,j]);
end;
sumsqr := sqrt(sumsqr);
for i := 1 to maxmatrix do
for j := 1 to maxmatrix do
begin
inputCoeffs[i,j] := 100.0*inputcoeffs[i,j]/sumsqr; // NORMALIZE TO 100
w[j,i] := inputCoeffs[i,j] {W = transpose(inputCoeffs)}
end;
dt := 0.0002;
ko := 1;
end;

procedure initprogram;
begin
randomize; // keep random function from repeating
with multicontrol do // MULTICONTROL IS NAME OF FORM
begin
maxmatrix := setnumpts.value; // SET BY SPINNER 0N SCREEN
initmatrix;
maxy := clientheight;
maxx := clientwidth;
stage := 0;
end;
niter := 0;
end;

procedure iterate;
var i: integer;
begin
if pause then exit;
case stage of
1: with multicontrol,canvas do
begin
initprogram;
brush.color := clSilver;
StartStop.font.Color := clRED;
StartStop.caption := 'STOP';
niter := 0;
stage := 2;
end;
2: begin
controlloops;
ersq := 0.0;
for i := 1 to maxmatrix do ersq := ersq + sqr(e[i]);
ersq := sqrt(ersq/maxmatrix);
showvariables;
inc(niter);
end;
end;
end;

// ITERATE ON NEXT IDLE CYCLE
procedure TMulticontrol.idleloop(Sender: TObject; var Done: boolean);
begin
done := false;
iterate;
end;

procedure TMultiControl.StartStopClick(Sender: TObject); // STOP PROGRAM
begin
application.terminate;
end;

procedure TMultiControl.SinePatClick(Sender: TObject); // SET REFERENCE LEVELS
var i: integer;
begin
initmatrix;
for i := 1 to maxmatrix do
r[i] := 1000*sin(i*2*pi/maxmatrix);
with multicontrol, canvas do
fillrect(rect(0,50,clientwidth,clientheight));
x := 0;
end;

procedure TMultiControl.CosinePatClick(Sender: TObject);// SET REFERENCE LEVELS
var i: integer;
begin
initmatrix;
for i := 1 to maxmatrix do
r[i] := -1000*cos(i*2*pi/maxmatrix);
with multicontrol, canvas do
fillrect(rect(0,50,clientwidth,clientheight));
x := 0;
end;

procedure TMultiControl.SetNumPtsChange(Sender: TObject);// SET NUM POINTS
begin
initprogram;
with multicontrol, canvas do
fillrect(rect(0,0,clientwidth,clientheight)); //; clear screen
x := 0;
stage := 1;
randomize;
end;

procedure TMultiControl.CreateMulti(Sender: TObject);
var i: integer;
begin
application.onIdle := idleloop; // set up call when idle begins
maxmatrix := setnumpts.value; // SET BY SPINNER 0N SCREEN
for i := 1 to maxmatrix do
stage := 1;
end;

procedure TMultiControl.Button1Click(Sender: TObject); // PAUSE BUTTON
begin
pause := not pause;
if pause then button1.caption := 'CONTINUE'
ELSE BUTTON1.Caption := 'PAUSE';
end;

end.

No virus found in this outgoing message.
Checked by AVG - http://www.avg.com
Version: 8.0.173 / Virus Database: 270.8.1/1731 - Release Date: 10/17/2008 7:01 PM

[from Tracy B. Harms (2008-10-18 12:01 Pacific)]

In reply to Bill Powers (2008.10.18.0242 MDT)

...
Appended is a cleaned-up version of my program, with simplified parameters.
The gain parameter is no longer adjustable, and the smallest number of
control systems is 5. If you use the given values of dt (0.0002) and ko
(1.0), the systems will be stable for all numbers of systems from 5 to 500.

Thanks, Bill. I've adjusted dt and ko in my program, and adjusted the
output to display only the difference between reference and
perception.

It looks to me as though the results don't count as stable because
typically error grows continually for some systems. Here's an example
session:

act^:(10^i.6)''
0.673687 _1.60622 _0.104572 0.158435 _1.2958
0.820381 _0.218164 _0.560167 0.101975 0.351175
0.819681 _0.230858 _0.551874 0.102072 0.365966
0.812717 _0.406405 _0.475411 0.103047 0.552861
0.746247 _116.171 _0.106994 0.113334 34.2267
0.31792 _4.23157e26 _3.56669e_8 0.293498 2.83047e19
act^:(100000)''
0.123191 _8.25941e53 _2.77556e_13 0.844823 2.29184e39
act^:(100000)''
0.0477353 _1.61211e81 _2.77556e_13 2.43179 1.8557e59
act^:(100000)''
0.018497 _3.14661e108 _2.77556e_13 6.9998 1.50257e79

The first six lines of output show the error under the initial
situation, after one iteration, ten further iterations, then 100,
1000, 10000, and 100000 further iterations. The next three runs add
another hundred thousand iterations each.

Numbering these five systems from zero through four, I notice that
systems 0, 2, and 3 maintain relatively low error but systems 1 and 4
have ever-increasing error.

Does this suggest that I've mishandled some aspect of the translation?

Tracy

···

___________________________________________________________________
NB. William T. Powers' matrix-transpose model
NB. translated to J by Tracy Harms (EARLY DRAFT, 2008-10-18)
NB. wtpmtm.ijs

size=: 5 NB. count of control systems in
this network
wco=: |: wci=: 1-~2* ? 0 \$~ 2# size NB. weighting coefficients,
input and output
ko=: 1
dt=: 0.0002
ps=: size # 0
oe=: size # 0
vs=: 1-~2* ? size # 0
rs=: 1-~2* ? size # 0

act=: verb define
ps=: vs (+/"_1 . *) wci NB. perceived situation
oe=: oe + (ko*dt) * rs - ps NB. output effect (alters factors)
vs=: oe (+/"_1 . *) wco NB. variable-factor situation
rs-ps NB. output for display during testing
)

As usual, the executable program is attached with its extension changed to
.txt. Change it back to .exe to run the program.

Every time you click on Sine or Cosine or change the number of systems, a
new matrix of random input weights is generated, and the output matrix is
set to the transpose of the input matrix. For some matrices, convergence
will be slow and the values of the outputs and environmental variables will
be very large. These are the matrices whose determinants approach zero,
indicating that no solution exists. The chances of a truly unsolvable system
are very close to zero (a state of pure conflict). However, as that state is
approached, outputs oppose each other more and more, so if the control
systems have limits on the amount of output they can generate, control will
be lost for relatively mild degrees of conflict.

Note that many hundreds of iterations are needed to reach final convergence,
since each iteration represents only a small interval of time. If you can
make the J program loop some number of times each time you initiate a
calculation, you may get a better test of how the program is working.

Note also that while the perceptual signals will approach the reference
signals, the outputs and environmental variables will not show any orderly
relationships. It occurs to me that this demonstration may be the final
disproof of the principle of behaviorism, because the regularities in these
collections of control systems are not detectable through observing their
behavior -- their outputs.

best,

Bill P.

==============================================================================
unit MultiControlUnit;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ComCtrls, Spin;

type
TMultiControl = class(TForm)
Panel1: TPanel;
SinePat: TButton;
CosinePat: TButton;
SetNumPts: TSpinEdit;
Label2: TLabel;
StartStop: TButton;
Button1: TButton;
Label1: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
procedure StartStopClick(Sender: TObject);
procedure SinePatClick(Sender: TObject);
procedure CosinePatClick(Sender: TObject);
procedure SetNumPtsChange(Sender: TObject);
procedure CreateMulti(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure idleloop(Sender: TObject; var Done: boolean);
end;

var
MultiControl: TMultiControl;

implementation

{\$R *.dfm}

const maxmax = 501;

type coefftype = array[1..maxmax, 1..maxmax] of double;
vectortype = array[1..maxmax] of double;

var qi, p, e, o, r: vectortype;
inputCoeffs,w: coefftype;
oldr, oldp, oldq, oldo: array[1..maxmax] of integer;
x, maxy, maxx, stage: integer;
dt,ko: double;
ersq: double;
niter,maxmatrix: integer;
pause: boolean;

{v2 = M*v1 premultiply vector by square matrix}
procedure MV(var M:coefftype; var v1, v2: vectortype);
var i,j: integer;
begin
for i := 1 to maxmatrix do
begin
v2[i] := 0.0;
for j := 1 to maxmatrix do
v2[i] := v2[i] + M[i,j]*v1[j]
end;
end;

{ C = A - B Vector subtract}
procedure VS(var A,B,C: vectortype);
var i: integer;
begin
for i := 1 to maxmatrix do
C[i] := A[i] - B[i];
end;

{ C = A + B vector add}
procedure VA(var A,B,C: vectortype);
var i: integer;
begin
for i := 1 to maxmatrix do
C[i] := A[i] + B[i];
end;

{B = k*int(A) vector integrate}
procedure VI(var a,b: vectortype; k: double);
var i: integer;
begin
for i := 1 to maxmatrix do
b[i] := b[i] + k*a[i]*dt;
end;

{ CONTROL LOOPS IMPLEMENTED AS (SQUARE) MATRIX OPERATIONS}
procedure controlloops;
begin
MV(inputCoeffs,qi, p); { p = coeffs*qi}
VS(r,p,e); { e = r - p}
VI(e,o,ko); { o = o + ko * integral(e) * dt}
MV(w,o,qi); { qi = w * o}
end;

{\$J+}
procedure showvariables;
var i,j,y: integer;
s: double;
begin
s := (maxx - 15)/(maxmatrix - 1); // SET X SCALE FOR PLOTTING
y := multicontrol.clientheight - round(ersq/2);
if niter >= 5000 div maxmatrix then
with multicontrol, canvas do
begin
font.color := clRed;
textout(10,clientheight-15,'RMS ERROR'); // REFRESH LEGEND
end;
if (niter mod 500) = 0 then // PLOT EVERY 500TH ITERATION
with multicontrol,canvas do
begin
color := clSilver;
pen.color := RGB(0,180,255);
font.Color := clRed;
ellipse(5+x - 2,y - 2,5+x + 2,y + 2);
x := x + 1;
if x >= clientwidth - 30 then x := 0;
if ((niter mod 15000) = 0) or (niter = 1) then
begin
fillrect(rect(x + 5,y,x + 105,y + 15));
textout(x+5,y - 14,floattostrf(ersq/5,fffixed,5,0));
end;
end;
if (niter mod 150) = 0 then
for i := 1 to maxmatrix do
with multicontrol,canvas do
begin
j := round(s*(i-1)) + 3;
pen.Color := clSilver;
brush.Color := clSilver;
ellipse(j-5,maxy div 2 - oldr[i] - 5,j+5,maxy div 2 - oldr[i] + 5);
ellipse(j-3,maxy div 2 - oldp[i] - 3,j+3,maxy div 2 - oldp[i] + 3);
ellipse(j-3,maxy div 2 - oldq[i] - 3,j+3,maxy div 2 - oldq[i] + 3);
ellipse(j-3,maxy div 2 - oldo[i] - 3,j+3,maxy div 2 - oldo[i] + 3);
oldr[i] := round(r[i] /5.0);
oldp[i] := round(p[i] /5.0);
oldq[i] := round(qi[i] /5.0);
oldo[i] := round(o[i]/5.0);
pen.color := clAqua;
brush.color := clAqua;
ellipse(j-5,maxy div 2 - oldr[i] - 5,j+5,maxy div 2 - oldr[i] + 5);
pen.color := RGB(250,0,0);
brush.color := RGB(250,0,0);
ellipse(j-3,maxy div 2 - oldp[i] - 3,j+3,maxy div 2 - oldp[i] + 3);
pen.Color := clYellow;
brush.color := clYellow;
ellipse(j-3,maxy div 2 - oldq[i] - 3,j+3,maxy div 2 - oldq[i] + 3);
pen.Color := clBlack;
brush.color := clBlack;
ellipse(j-3,maxy div 2 - oldo[i] - 3,j+3,maxy div 2 - oldo[i] + 3);
brush.Color := clSilver;
end;
end;

procedure initmatrix;
var i,j: integer;
sumsqr: double;
begin
sumsqr := 0.0;
for i := 1 to maxmatrix do
for j := 1 to maxmatrix do // LOAD RANDOM INPUT COEFFICIENTS, -1 TO 1
begin
inputCoeffs[i,j] := 1.98*(random - 0.5);
sumsqr := sumsqr + sqr(inputCoeffs[i,j]);
end;
sumsqr := sqrt(sumsqr);
for i := 1 to maxmatrix do
for j := 1 to maxmatrix do
begin
inputCoeffs[i,j] := 100.0*inputcoeffs[i,j]/sumsqr; // NORMALIZE TO 100
w[j,i] := inputCoeffs[i,j] {W = transpose(inputCoeffs)}
end;
dt := 0.0002;
ko := 1;
end;

procedure initprogram;
begin
randomize; // keep random function from repeating
with multicontrol do // MULTICONTROL IS NAME OF FORM
begin
maxmatrix := setnumpts.value; // SET BY SPINNER 0N SCREEN
initmatrix;
maxy := clientheight;
maxx := clientwidth;
stage := 0;
end;
niter := 0;
end;

procedure iterate;
var i: integer;
begin
if pause then exit;
case stage of
1: with multicontrol,canvas do
begin
initprogram;
brush.color := clSilver;
StartStop.font.Color := clRED;
StartStop.caption := 'STOP';
niter := 0;
stage := 2;
end;
2: begin
controlloops;
ersq := 0.0;
for i := 1 to maxmatrix do ersq := ersq + sqr(e[i]);
ersq := sqrt(ersq/maxmatrix);
showvariables;
inc(niter);
end;
end;
end;

// ITERATE ON NEXT IDLE CYCLE
procedure TMulticontrol.idleloop(Sender: TObject; var Done: boolean);
begin
done := false;
iterate;
end;

procedure TMultiControl.StartStopClick(Sender: TObject); // STOP PROGRAM
begin
application.terminate;
end;

procedure TMultiControl.SinePatClick(Sender: TObject); // SET REFERENCE
LEVELS
var i: integer;
begin
initmatrix;
for i := 1 to maxmatrix do
r[i] := 1000*sin(i*2*pi/maxmatrix);
with multicontrol, canvas do
fillrect(rect(0,50,clientwidth,clientheight));
x := 0;
end;

procedure TMultiControl.CosinePatClick(Sender: TObject);// SET REFERENCE
LEVELS
var i: integer;
begin
initmatrix;
for i := 1 to maxmatrix do
r[i] := -1000*cos(i*2*pi/maxmatrix);
with multicontrol, canvas do
fillrect(rect(0,50,clientwidth,clientheight));
x := 0;
end;

procedure TMultiControl.SetNumPtsChange(Sender: TObject);// SET NUM POINTS
begin
initprogram;
with multicontrol, canvas do
fillrect(rect(0,0,clientwidth,clientheight)); //; clear screen
x := 0;
stage := 1;
randomize;
end;

procedure TMultiControl.CreateMulti(Sender: TObject);
var i: integer;
begin
application.onIdle := idleloop; // set up call when idle begins
maxmatrix := setnumpts.value; // SET BY SPINNER 0N SCREEN
for i := 1 to maxmatrix do
stage := 1;
end;

procedure TMultiControl.Button1Click(Sender: TObject); // PAUSE BUTTON
begin
pause := not pause;
if pause then button1.caption := 'CONTINUE'
ELSE BUTTON1.Caption := 'PAUSE';
end;

end.

No virus found in this outgoing message.
Checked by AVG - http://www.avg.com
Version: 8.0.173 / Virus Database: 270.8.1/1731 - Release Date: 10/17/2008
7:01 PM