ECOLI4a: Reality Check

[From Bruce Abbott [941116.1640 EST)]

For those of you who are having trouble believing that ECOLI4a really works as
advertised, and have resorted to strange computer simulations that give
probabilities of around 0.5 no matter what, please try the simulation below,
which gives the correct probabilities according to my model.

[Kahn fires a second photon torpedo at the Enterprise, striking a direct hit
on the bridge. A large piece of the superstructure crashes to the floor,
narrowly missing Kirk.]

Kirk: Computer! Give me our options and their probabilities of success!

Computer: Do you want the Marken probabilities or the brutal truth?

Bruce [;->

···

------------------------------------------------------------------------------
program Tumble;

{ Generates probabilities given S+ (nutrients rising) and
  S- (nutrients falling) that a random tumble will produce an
  increased nutrient rate after tumble) or a decreased nutrient
  rate after tumble. The theoretical probabilities are:

                       Increase>S+ = 0.25;
                       Decrease>S+ = 0.75;
                       Increase>S- = 0.75;
                       Decrease>S- = 0.25;

  These probabilities are sampled by ECOLI4a and provide the basis
  of its ability to learn that (a) 'tis better to tumble when things are
  bad (negative nutrient change), and (b) 'this better not to tumble when
  things are good (positive nutrient change).

  Bruce Abbott
  11/16/94 }

uses
  CRT;

var
  Ch: char;
  Trial: longint;
  count: array [1..4] of longint;
  p: array [1..4] of real;

procedure Init;
var
  i: integer;
begin
  ClrScr;
  gotoXY(20, 10); write(' COUNT PROB|S TRIAL');
  gotoXY(10, 11); write('Reinf|S+');
  gotoXY(10, 12); write('Punis|S+');
  gotoXY(10, 13); write('Reinf|S-');
  gotoXY(10, 14); write('Punis|S-');
  gotoXY(10, 24); write('Press ESC to quit . . .');
  Trial := 0;
  for i := 1 to 4 do
    begin
      count[i] := 0;
      p[i] := 0.0;
    end;
  Ch := #0;
end;

procedure TestTumble;
var
  dNutA, dNutB, Diff: real;
begin
  inc(Trial);
  dNutB := random - 0.5; { random rate before tumble }
  dNutA := random - 0.5; { another random rate after tumble }
  Diff := dNutA - dNutB;
  if dNutB > 0 then
    if Diff > 0 then inc(count[1]) else inc(count[2])
  else
    if Diff > 0 then inc(count[3]) else inc(count[4]);
end;

procedure WriteData;
var
  i: integer;
  TotalSplus, TotalSminus: longint;
begin
  TotalSplus := count[1] + count[2];
  TotalSminus := count[3] + count[4];
  for i := 1 to 2 do
    begin
      p[i] := count[i]/TotalSplus;
      gotoXY(20, 10+i); write(count[i]:10, p[i]:10:4);
    end;
  for i := 1 to 2 do
    begin
      p[i] := count[i]/TotalSminus;
      gotoXY(20, 12+i); write(count[i]:10, p[i]:10:4);
    end;
    gotoXY(40, 11); write(Trial:10);
end;

begin
  Init;
  repeat
    TestTumble;
    if Trial MOD 100 = 0 then WriteData;
    if keypressed then Ch := Readkey;
  until (Ch = #27) or (Trial = 200000);
  Ch := Readkey;
end.