# another challenge won

**URL:** <http://discourse.iapct.org/t/another-challenge-won/13048>\
**Category:** CSG1995\
**Created:** [September 27, 1995, 10:22am UTC](http://discourse.iapct.org/t/another-challenge-won/13048 "1995-09-27T10:22:50Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![HANS\_BLOM2](http://discourse.iapct.org/letter_avatar_proxy/v4/letter/h/f17d59/32.png) [@HANS\_BLOM2](http://discourse.iapct.org/u/HANS_BLOM2)\
**Post date:** [September 27, 1995, 10:22am UTC](http://discourse.iapct.org/t/another-challenge-won/13048/1 "1995-09-27T10:22:50Z")

</div>

[Hans Blom, 950927]

Here are the results of our new challenge, model-based versus PCT  
control. As before, the smaller the RMS ERROR, the better the con-  
troller.

The "real world" is:

&nbsp;&nbsp;x [i] := k [i] \* u [i] + d1 [i]

where

&nbsp;&nbsp;k [i] := 3.0 + 2.0 \* d2 [i] / 1000.0

and d1 [i] and d2 [i] are low pass filtered random sequences.

My model of the "world" is:  
&nbsp;&nbsp;^ ^ ^  
&nbsp;&nbsp;x [i] := k [i] \* u [i] + d [i]

where for the "noise" terms k and d I assume:  
&nbsp;&nbsp;^ ^  
&nbsp;&nbsp;k [i] := k [i-1] + m [i]  
&nbsp;&nbsp;^ ^  
&nbsp;&nbsp;d [i] := d [i-1] + n [i]

"Hats" above variables denote estimates and m and n are assumed to  
be (unknown) random noise. The model's prediction is called x-hat,  
and it is this value that determines how to control. The observed  
value (the "real" x) is called y, and it is this value that is used  
to update the model -- and thus only indirectly to control.

Note that this program models a simpler noise than my previous  
program did: no first derivative term, just a zero order hold,  
i.e. both k and d are assumed to remain constant from iteration to  
iteration. No doubt the derivative method would be even better.

But the challenge results below show that the quality of control  
does not depend on derivatives but on the fact that \_knowledge  
accumulation\_ takes place, which makes \_prediction\_ possible. Even  
this simplest possible kind of prediction provides quite an  
improvement over the PCT method: the PCT controller's RMS error  
is from 50% to more than 100% larger.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bill/PCT control Hans/model-based  
Slowing = 0.01 RMS ERROR = 10.5 RMS ERROR = 7.5  
Slowing = 0.02 RMS ERROR = 15.0 RMS ERROR = 7.4  
Slowing = 0.03 RMS ERROR = 22.5 RMS ERROR = 10.7  
Slowing = 0.04 RMS ERROR = 30.1 RMS ERROR = 14.2  
Slowing = 0.05 RMS ERROR = 34.3 RMS ERROR = 15.6  
Slowing = 0.06 RMS ERROR = 37.5 RMS ERROR = 18.5  
Slowing = 0.07 RMS ERROR = 43.5 RMS ERROR = 20.8  
Slowing = 0.08 RMS ERROR = 44.8 RMS ERROR = 20.7  
Slowing = 0.09 RMS ERROR = 56.2 RMS ERROR = 30.2  
Slowing = 0.10 RMS ERROR = 61.1 RMS ERROR = 31.3  
Slowing = 0.11 RMS ERROR = 68.2 RMS ERROR = 36.0  
Slowing = 0.12 RMS ERROR = 70.4 RMS ERROR = 37.2  
Slowing = 0.13 RMS ERROR = 78.7 RMS ERROR = 40.1  
Slowing = 0.14 RMS ERROR = 89.7 RMS ERROR = 44.1  
Slowing = 0.15 RMS ERROR = 91.8 RMS ERROR = 45.5  
Slowing = 0.16 RMS ERROR = 92.6 RMS ERROR = 49.1  
Slowing = 0.17 RMS ERROR = 102.1 RMS ERROR = 59.5  
Slowing = 0.18 RMS ERROR = 104.6 RMS ERROR = 60.0  
Slowing = 0.19 RMS ERROR = 108.0 RMS ERROR = 58.0  
Slowing = 0.20 RMS ERROR = 110.9 RMS ERROR = 63.9

As before, the first iteration's error is not added to the sum of  
the total RMS error, because a model-based controller needs this  
iteration to initialize itself. As before, to be fair, I added the  
same change to Bill's program. This is my code (except for some  
declarations of variables):

sum := 0.0;  
u := 0.0;

{initial estimates; quite robust for different assumptions}  
k := 0.1; kold := 0.1; pmm := 100.0; pkk := 10000.0;  
d := 0.0; dold := 0.0; pnn := 1000000.0; pdd := 10000.0;  
pdk := 0.0;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{RUN THE MODEL MAXTABLE TIMES}  
{============================================================}  
for i := 0 to maxtable - 1 do  
begin

&nbsp;&nbsp;{control; compute u}  
&nbsp;&nbsp;if k = 0.0 then  
&nbsp;&nbsp;&nbsp;&nbsp;u := 0.0 {cannot control, so don't}  
&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;u := (r [i] - d) / k;

&nbsp;&nbsp;{prediction; at this moment, u is known}  
&nbsp;&nbsp;x := k \* u + d;  
&nbsp;&nbsp;pxx := pkk \* sqr (u) + 2.0 \* pdk \* u + pdd;  
&nbsp;&nbsp;pxk := pkk \* u + pdk;  
&nbsp;&nbsp;pxd := pdk \* u + pdd;  
&nbsp;&nbsp;pkk := pkk + pmm;  
&nbsp;&nbsp;pdd := pdd + pnn;

&nbsp;&nbsp;{get response of the "world"}  
&nbsp;&nbsp;y := (3.0 + 2.0 \* d2 [i] / 1000.0) \* u + d1 [i];

&nbsp;&nbsp;{correction; at this moment, y is the response to u}  
&nbsp;&nbsp;k := k + (y - x) \* pxk / pxx;  
&nbsp;&nbsp;d := d + (y - x) \* pxd / pxx;  
&nbsp;&nbsp;pkk := pkk - sqr (pxk) / pxx;  
&nbsp;&nbsp;pdd := pdd - sqr (pxd) / pxx;  
&nbsp;&nbsp;pdk := pdk - pxd \* pxk / pxx;

&nbsp;&nbsp;{estimate of m and n noise variances}  
&nbsp;&nbsp;pmm := pmm + (sqr (k - kold) - pmm) / 20.0; kold := k;  
&nbsp;&nbsp;pnn := pnn + (sqr (d - dold) - pnn) / 20.0; dold := d;

&nbsp;&nbsp;if i \> 0 then {allow one iteration for initialization}  
&nbsp;&nbsp;sum := sum + sqr(r[i] - y); { ACCUMULATE FOR RMS ERROR }  
end;  
{============================================================}  
sum := sqrt(sum / (maxtable));

Bill, check and see. Satisfied? Rick?

Greetings,

Hans
