[From Bill Powers (950103.1300 MST)]

Bob Clark:

Glad your recovery is far enough along for you to be back on the net.

## ···

---------------------------------------------------------------------

Bruce Abbott, Rick Marken, Tom Bourbon, anyone else interested:

I've worked up an experimental demo to help us work out how to talk

about differences in methodology. A participant moves a mouse that

affects three objects on a display: a square that changes size, a

rectangle that changes shape, and a line that changes angle. All three

objects are affected by the (x-axis) mouse movement; each object is also

affected by an independent disturbance. A more detailed description is

given as a comment preceding the code below. I've also appended the

source code for a mouse.pas unit in case I haven't already done that.

The code provided allows doing an experimental run and saving the handle

positions in a heap array. The participant chooses one object to control

and holds it constant during the run.

The dimensions of the rectangles are saved in arrays as

size

shapex

shapey

The position of the top of the line is saved as

angle

with the bottom of the line always being at maxy div 2 - 80;

The question is how, under different methodologies, the data would be

handled. Given the dimensions of the rectangles and the position of the

top of the line as inputs or stimuli, and the mouse positions as

measures of response, what would the normal statistical analysis be? I

think that the dimensions of the stimuli would be used as independent

variables, and the mouse behavior would be treated as a dependent

variable. But the program leaves the analysis open. I can supply a PCT

analysis; what we need for comparison is another analysis, or several

others (perhaps an IV-DV analysis, an ANOVA, and an EAB analysis).

This situation is meant to represent a "wild" situation in which we can

see a given behavior and a number of different effects it is having on

the environment. There are also disturbances which become known only

through their effects on the environmental variables (their causes are

not visible, although we know what they are). The question is how we go

about determining what is happening according to various traditional

approaches as well as that of PCT.

If we can come up with a good systematic comparison of methods, and can

draw the necessary parallels between this demonstration and the real

situations in which we find real behavior, this may be worth a paper.

The particular situation I present below is not set in stone;

alternatives gladly received.

Best to all,

# Bill P.

Program threecv;

{ A PROGRAM FOR TESTING METHODS OF ANALYSIS

required: setparam.pas revision of 941220; mouse unit

Horizontal mouse movements affect the shape of one object, the size

of another, and the angle of a line. Each object is disturbed by a

different disturbance pattern. The participant uses horizontal (only)

mouse position to maintain the green object as a rectangle of constant

shape, the white object as a square of constant size, or the red line

pointing at a constant angle. The purpose of the program is to provide

data from real human control behavior to see how the conventional and

PCT approaches would analyze them. The basic question to be answered is

"What is the relationship between the three variables shown on the

screen and the handle movements?" The analysis portion of the program

is left to the user to develop (a dummy procedure called "analyze"

in the code below).

When the program starts, the first disturbance is shown on the screen.

Pressing the space bar generates a new pattern, pressing escape accepts

that pattern and goes on to the next of three disturbances. After the

third disturbance pattern is accepted, the program pauses (to allow

the participant to select which variable to control). When a key is

struck, the one-minute run starts with a run-in time (not recorded)

of 2 seconds to allow gaining control. MAXDATA data points are recorded.

The three disturbances are stored in arrays of MAXDATA integers on the

heap,

dist1[], dist2[], and dist3[]. The mouse position is also stored in an

array on the heap, handle[]. Entries are accessed as distn^[i] or

handle^[i] for i from 1 to MAXDATA.

For the size-controlled object, both dimensions are increased by a

mouse movement to the right. A convenient measure of size is

x = y = 80 + (handle^[i] + dist1^[i]) div 3.

The shape can be characterized in terms of the difference between

width and height of the rectangle. A convenient measure of shape is

x - y where

x = 80 + (handle^[i] + dist2^[i]) div 5.

y = 80 - (handle^[i] + dist2^[i]) div 5.

when x = y the shape is square.

For the line, the angle of lean moves to the right for a mouse

movement to the right. A convenient measure of the orientation

is

tan(angle from vertical) = (handle^[i] + dist3^[i])/160.

The dimensions of the rectangles are saved in arrays size,

shapex, and shapey. The x-position of the top of the line is saved

in array angle. All are integer arrays on the heap.

}

Uses Dos,Crt,Graph,grUtils,mouse;

const

left = 203; right = 205; up = 200; down = 208; PgUp = 201; PgDn = 209;

Ins = 210; Del = 211; EndKey = 207; Home = 199; EscKey = 27; Cr = 13;

f1 = 187; f2 = 188; f3 = 189; f4 = 190; f5 = 191;

f6 = 192; f7 = 193; f8 = 194; f9 = 195; f10 = 196;

MAXDATA = 3600;

type dataarray = array[1..MAXDATA] of integer;

dataptr = ^dataarray;

var i,j,maxx,maxy: integer;

slow,d1,d2,d3: real;

maxcolor: word;

dist1,dist2,dist3: dataptr;

size,shapex,shapey,angle: dataptr;

handle: dataptr;

ch: char;

procedure InitScreen;

begin

ClrScr;

InitGraphics;

MaxX := GetMaxX; MaxY := GetMaxY;

maxColor := getmaxcolor;

end;

procedure labelscreen;

begin

setcolor(lightgreen);

outtextxy(0,0,'KEEP SIZE CONSTANT');

setcolor(lightred);

outtextxy(0,20,'KEEP POINTER AT CONSTANT ANGLE');

setcolor(white);

outtextxy(0,40,'KEEP SHAPE CONSTANT');

outtextxy(0,80,'PRESS SPACE TO START RUN');

end;

procedure InitDist(d: dataptr);

var i,max: integer;

avg,tmp: real;

begin

repeat

clearviewport;

outtextxy(0,0,'PRESS SPACE FOR NEW PATTERN, ESC KEY TO ACCEPT');

if d = dist1 then outtextxy(0,20,'FIRST DISTURBANCE')

else

if d = dist2 then outtextxy(0,20,'SECOND DISTURBANCE')

else

if d = dist3 then outtextxy(0,20,'THIRD DISTURBANCE');

d1 := 0.0; d2 := 0.0; d3 := 0.0;

for j := -100 to MAXDATA do

begin

i := abs(j) + 1;

d1 := random * 10000.0 - 5000.0;

d2 := d2 + slow*(d1 - d2);

d3 := d3 + slow*(d2 - d3);

d^[i] := round(d3);

if j > 0 then

putpixel(i div 6,maxy div 2 - d^[i] div 2,white);

end;

avg := 0.0;

for i := 1 to MAXDATA do avg := avg + d^[i];

avg := avg/MAXDATA;

for i := 1 to MAXDATA do d^[i] := d^[i] - round(avg);

max := 0;

for i := 1 to MAXDATA do if abs(d^[i]) > max then max := abs(d^[i]);

for i := 1 to MAXDATA do

begin

tmp := 80.0/max;

d^[i] := round(d^[i]*tmp);

end;

ch := readkey;

until ch = chr(EscKey);

end;

var oldsizex,oldsizey: integer;

procedure drawsize(h,d,init: integer);

var x0,y0: integer;

begin

setcolor(lightgreen);

x0 := maxx div 2; y0 := maxy div 2;

if init = 0 then

rectangle(x0 - oldsizex,y0 - oldsizey,

x0 + oldsizex,y0 + oldsizey);

oldsizex := 80 + (h + d) div 3;

oldsizey := 80 + (h + d) div 3;

rectangle(x0 - oldsizex,y0 - oldsizey,

x0 + oldsizex,y0 + oldsizey);

setcolor(white);

end;

var oldanglex,oldangley: integer;

procedure drawangle(h,d,init: integer);

var x0,y0: integer;

begin

setcolor(lightred);

x0 := maxx div 2; y0 := maxy div 2 + 80;

if init = 0 then

line(x0,y0,oldanglex,oldangley);

oldanglex := x0 + (h+d) div 3;

oldangley := y0 - 80;

line(x0,y0,oldanglex,oldangley);

setcolor(white);

end;

var oldshapex,oldshapey: integer;

procedure drawshape(h,d,init: integer);

var x0,y0: integer;

begin

x0 := maxx div 2; y0 := maxy div 2;

if init = 0 then

rectangle(x0 - oldshapex,y0 - oldshapey,

x0 + oldshapex,y0 + oldshapey);

oldshapex := 80 + (h+d) div 5;

oldshapey := 80 - (h+d) div 5;

rectangle(x0 - oldshapex,y0 - oldshapey,

x0 + oldshapex,y0 + oldshapey);

end;

procedure RunExpt;

var h: integer;

begin

readmouse;

drawsize(mousex,dist1^[120],1);

drawshape(mousex,dist2^[120],1);

drawangle(mousex,dist3^[120],1);

for j := -120 to MAXDATA do

begin

i := abs(j) + 1;

readmouse;

h := mousex;

handle^[i] := h;

retrace;

drawsize(mousex,dist1^[i],0);

drawshape(mousex,dist2^[i],0);

drawangle(mousex,dist3^[i],0);

{ save object variables}

shapex^[i] := oldshapex;

shapey^[i] := oldshapey;

size^[i] := oldsizex;

angle^[i] := oldanglex;

if j = -120 then ch := readkey;

if keypressed then break;

end;

if keypressed then ch := readkey;

end;

procedure Analyze;

begin

end;

# begin

ClrScr;

if not initmouse then

begin

gotoxy(20,10);

writeln('MOUSE NOT INSTALLED. EXITING');

delay(2000);

exit;

end;

new(dist1);

new(dist2);

new(dist3);

new(size);

new(shapex);

new(shapey);

new(angle);

new(handle);

Randomize;

slow := 0.005;

InitScreen;

InitDist(dist1);

InitDist(dist2);

InitDist(dist3);

clearviewport;

labelscreen;

setwritemode(XORPUT);

RunExpt;

Analyze;

RestoreCrtMode;

closegraph;

dispose(handle);

dispose(angle);

dispose(shapey);

dispose(shapex);

dispose(size);

dispose(dist3);

dispose(dist2);

dispose(dist1);

end.

# Here is a simple mouse.pas unit

unit mouse;

interface

uses dos,crt;

var mousex,mousey: integer;

function initmouse: boolean;

function readmouse: integer;

function readbutton: integer;

implementation

var MouseR : registers;

dx,dy: real;

{ ---------------------- Mouse Functions---------------------}

function initmouse: boolean;

begin { false if mouse not found }

mousex := 0; mousey := 0;

dx := 0; dy := 0;

MouseR.ax := 0;

intr ($33, mouser);

if Mouser.ax <> $ffff then

begin

writeln('MOUSE NOT INSTALLED');

delay(1000);

end;

Initmouse := (MouseR.ax = $ffff);

end;

function readmouse: integer;

begin

mouser.ax := 11;

intr ($33, mouser);

dx := dx + 0.4*(integer(MouseR.cx) - dx);

dy := dy + 0.4*(integer(MouseR.dx) - dy);

mousex := mousex + round(dx);

mousey := mousey - round(dy);

end;

function readbutton: integer; { returns 1,2,or 4}

begin

MouseR.ax := 3;

intr ($33, MouseR);

readbutton := MouseR.bx and 3;

end;