home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
TURBOPAS
/
MAPSTATF.LBR
/
TRANSFRM.PZS
/
TRANSFRM.ÐAS
Wrap
Text File
|
2000-06-30
|
12KB
|
340 lines
(* Multivariate Analysis Package - Data Transformation Module
Copyright 1985 Douglas L. Anderton. This program may be
freely circulated so long as it is not sold for profit
and any charge does not exceed costs of reproduction *)
Program Transfrm(Input,Output);
Const
N=100;
Type
SUBS=1..N;
RVEC = Array [SUBS] Of Real;
RVE2 = Array [1..200] Of Real;
IVEC = Array [SUBS] Of Integer;
IVE2 = Array [1..200] Of SUBS;
ST12 = String[12];
TR = String[79];
TS = Array [SUBS] of TR;
Var
dfile, ofile, tfile : Text;
sel : IVEC;
sub : IVE2;
miss, vars, ho : RVEC;
cns : RVE2;
dv, fo, t : SUBS;
i, k, l, nv, nt : Integer;
trans: TS;
{$I TRANSBUF.LIB}
Procedure openfiles(Var dfile, ofile, tfile:Text; Var fo:SUBS);
Var
dfl, ofl:String[12];
Begin
ClrScr; Writeln(' *** TRANSFRM: DATA TRANSFORMATION ***');
Writeln; Write('Name of the input data file? ');
Readln(dfl); Assign(dfile,dfl); Reset(dfile);
Write('Name of output data file (con:/lst: not allowed)? ');
Readln(ofl);
If (ofl='CON:') Or (ofl='con:') Then ofl:='CONSOLE.TMP';
If (ofl='LST:') Or (ofl='lst:') Then ofl:='LIST.TMP';
initwrite(ofl);
Write('Name of the transformation file (or con:)? ');
Readln(dfl); Assign(tfile,dfl); Reset(tfile);
If (dfl='CON:') Or (dfl='con:') Then fo:=1 Else fo:=0;
End; (* Of openfiles *)
Procedure selectvar(Var sel:IVEC; Var miss:RVEC; Var nv:Integer; Var dv:SUBS);
Var
cfile:Text;
cfl:String[12];
i,j,f:Integer;
mis:Real;
van:String[8];
Begin
Write('Name of the codebook file (or NONE)? '); Readln(cfl);
If (cfl<>'NONE') And (cfl<>'none') Then f:=1 Else f:=0;
If f=1 Then Begin Assign(cfile,cfl); Reset(cfile); End;
Writeln;
Write('How many variables in data file? '); Readln(nv);
Write('Number of variables to use in TRANSFRM? '); Readln(dv);
For i := 1 To dv Do
Begin
Write('Column number for variable ',i,'? '); Readln(sel[i]);
miss[i]:=-1E37;
End;
If f=1 Then Begin
For j:=1 to nv Do Begin
mis:=-1E37;
Readln(cfile,f,van,mis);
For i:=1 to dv Do
If f=sel[i] Then Begin
miss[i]:=mis;
Writeln('Col: ',sel[i],' Name: ',van,' Missing: ',miss[i]:6);
End;
End;
Close(cfile);
End;
End; (* Of selectvar *)
Procedure prmenu2;
Begin
ClrScr; Writeln(' *** TRANSFRM: DATA TRANSFORMATION ***'); Writeln;
Writeln('Valid Arithmetic Operators:');
Writeln(' + - * / =');
Writeln('Turbo Pascal Functions Supported:');
Writeln(' ABS ARCTAN COS EXP FRAC INT');
Writeln(' LN SIN SQR SQRT ROUND TRUNC');
Writeln(' RANDOM');
Writeln('Nonstandard MAP functions supported:');
Writeln(' IF IFS LAG NORMAL POW REC');
Writeln('Number Entry:');
Writeln(' Leading minus allowed (not plus) number must be less than');
Writeln(' or equal to 11 digits, e.g. .001 12 -.0000005 etc.');
Writeln;
Writeln('Note: no check of statements is provided until runtime. [n]');
Writeln(' refers to the nth variable read, not the nth column.');
Writeln(' Comments may follow transformations on the same line');
Writeln(' except END statement. Functions must be UPPERCASE.');
Writeln;
End; (* of prmenu2 *)
Procedure prmenu;
Begin
ClrScr; Writeln(' *** TRANSFRM: DATA TRANSFORMATION ***'); Writeln;
Write('Data transformation statements are entered in RPN (reverse');
Writeln(' polish notation)');
Write('with blanks separating each operator, constant, or variable.');
Writeln(' Statements are');
Write('terminated by ''='' to end the statement and the variable');
Writeln(' number to receive');
Write('the value. Variables are referred to by column number');
Writeln(' in brackets ''[n]''.');
Write('New variables created by transformations are added to');
Writeln(' the data file. Use');
Write('successive numbers for new variables (if you read four');
Writeln(' variables the first');
Write('you create should be ''[5]'' etc.) ''END'' in the first');
Writeln(' three columns will end');
Writeln('input of transformations.');
Writeln;
Writeln('Examples:');
Write(' To put the square root of 3.2 times the first variable into');
Writeln(' the first -');
Writeln(' ->3.2 [1] * SQRT = [1]');
Write(' To create a new sixth variable as the natural logarithm of');
Writeln(' the second');
Writeln(' divided by the fifth -');
Writeln(' ->[5] [2] LN / = [6]');
Writeln(' To recode second variable if between 10 and 50 to value 3 -');
Writeln(' ->[2] 10 50 3 REC = [2]'); Writeln;
Writeln('A summary of available operators is displayed during entry.');
Writeln;
Write('- Press any key to continue -'); While Not KeyPressed Do;
ClrScr; prmenu2;
End; (* Of prmenu *)
Procedure getcase(Var vars:RVEC; sel:IVEC; nv, dv:SUBS; Var dfile:Text);
Var
i, j:SUBS;
x:Real;
Begin
For i := 1 To nv Do
Begin
Read(dfile,x);
For j := 1 To dv Do If (sel[j]=i) Then vars[j] := x;
End;
End; (* Of getcase *)
Procedure nextop(temp:TR; Var tstr: ST12; Var sgp:Integer);
Var k,l: SUBS;
Begin
k:=Pos(' ',Copy(temp,sgp,11));
tstr:=Copy(temp,sgp,k);
sgp:=sgp+k;
End; (* Of nextop *)
Function Tnum(Var t:Char): Boolean;
Begin Tnum:=false;
If(((t>='0') and (t<='9')) or (t='.')) Then Tnum:=True; End;
Procedure ParseNums(Var trans:TS; Var cns:RVE2; Var sub:IVE2);
Var
opr: Real;
i, t, f, cntp, subp: SUBS;
j, sgp, varn: Integer;
tstr: ST12;
temp: TR;
tstr1: Char;
Begin
FillChar(cns,6*200,0); FillChar(sub,200,0); cntp:=0; subp:=0;
i:=1; t:=0;
While (t=0) Do
Begin
sgp:=1; temp:=trans[i]; f:=0;
While (f<2) Do
Begin
nextop(temp,tstr,sgp);
tstr1:=tstr[1];
case tstr1 of
'-':If(Tnum(tstr[2])) Then Begin
Val(Copy(tstr,2,(Pos(' ',tstr)-1)),opr,j);
cntp:=cntp+1; cns[cntp]:=-opr; End;
'[':Begin Val(Copy(tstr,2,(Pos(']',tstr)-2)),varn,j);
subp:=subp+1; sub[subp]:=varn;
If(f>0) then f:=2; End;
'E':If(tstr[2]='N') Then Begin t:=1; f:=2; End;
'=':f:=1;
Else {of case check to see if it is a constant}
If(Tnum(tstr1)) Then Begin
Val(Copy(tstr,2,(Pos(' ',tstr)-1)),opr,j);
cntp:=cntp+1; cns[cntp]:=-opr; End;
End; (* of case *)
End; (* of this transform *)
i:=i+1;
End;
End; (* Of ParseNums *)
Procedure transform(Var vars, hold, miss:RVEC; cns:RVE2; sub:IVE2;
Var dv, t:SUBS; trans:TS);
Var
op1, op2, op3, op4: Real;
st: RVEC;
i, sp, tag, flg: SUBS;
j, sgp, varn, cntp, subp: Integer;
tstr: ST12;
temp: TR;
tstr1: Char;
Procedure push(ac: Real; Var st:RVEC; Var sp:SUBS);
Begin sp:=sp+1; st[sp]:=ac; End; (* Of push *)
Function pop(Var st:RVEC; Var sp:SUBS): Real;
Begin pop:=st[sp]; sp:=sp-1; End; (* Of pop *)
Procedure nextcnt(Var cntp:Integer; Var cns:RVE2; Var x:Real);
Begin cntp:=cntp+1; x:=cns[cntp]; End;
Procedure nextint(Var subp:Integer; Var sub:IVE2; Var x:Integer);
Begin subp:=subp+1; x:=sub[subp]; End;
Begin (* Of Transform *)
i:=1; t:=0; flg:=0; tstr:='?'; cntp:=0; subp:=0;
While ((tstr[1]<>'E') or (tstr[2]<>'N')) and (t=0) Do
Begin
FillChar(st,6*N,0);
sp:=0; sgp:=1; tag:=0; temp:=trans[i];
While (tag=0) Do
Begin
nextop(temp,tstr,sgp);
tstr1:=tstr[1];
case tstr1 of
'=': tag:=4;
'+': push((pop(st,sp)+pop(st,sp)),st,sp);
'*': push((pop(st,sp)*pop(st,sp)),st,sp);
'/': push((pop(st,sp)/pop(st,sp)),st,sp);
'-': If(Tnum(tstr[2])) Then Begin nextcnt(cntp,cns,op1);
op1:=-op1; push(op1,st,sp); End
Else push((pop(st,sp)-pop(st,sp)),st,sp);
'[':Begin nextint(subp,sub,varn); push(vars[varn],st,sp);
If(vars[varn]=miss[varn]) Then Begin
While (tstr[1]<>'=') Do nextop(temp,tstr,sgp); tag:=3; End;
End;
'I':If (tstr[3]='S') Then {ifs, if and int}
If(pop(st,sp)<0.0) Then tag:=2
Else tag:=5 (* keep record but stop loop *)
Else If(tstr[3]='T') Then push(Int(pop(st,sp)),st,sp)
Else If(pop(st,sp) < 0.0) Then tag:=1;
'E':If(tstr[2]='N') Then tag:=4 {exp and end}
Else push(Exp(pop(st,sp)),st,sp);
'L':If(tstr[2]='N') Then push(Ln(pop(st,sp)),st,sp) {ln and lag}
Else Begin op1:=pop(st,sp); push(hold[varn],st,sp);
hold[varn]:=op1; End;
'P':push(exp(pop(st,sp)*ln(pop(st,sp))),st,sp); {pow}
'S':If(tstr[2]='Q') Then {sqrt sqr and sin}
If(tstr[4]='T') Then push(Sqrt(pop(st,sp)),st,sp)
Else push(Sqr(pop(st,sp)),st,sp)
Else push(Sin(pop(st,sp)),st,sp);
'C':push(Cos(pop(st,sp)),st,sp); {cos}
'A':If(tstr[2]='B') Then push(abs(pop(st,sp)),st,sp) {abs and arctan}
Else push(ArcTan(pop(st,sp)),st,sp);
'T':push(Trunc(pop(st,sp)),st,sp); {trunc}
'F':push(Frac(pop(st,sp)),st,sp); {frac}
'R':If(tstr[2]='A') Then push(Random,st,sp) {random round and rec}
Else If(tstr[2]='O') Then push(Round(pop(st,sp)),st,sp)
Else Begin
op1:=pop(st,sp);op2:=pop(st,sp);
op3:=pop(st,sp);op4:=pop(st,sp);
If((op3<=op4) and (op4<=op2)) Then push(op1,st,sp)
Else push(op4,st,sp); End;
'N':Begin push(0.0,st,sp); {normal}
For j:=1 To 12 Do push((pop(st,sp)+Random),st,sp);
push((pop(st,sp)-6.0),st,sp); End;
Else {of case check to see if it is a constant}
If(Tnum(tstr1)) Then Begin nextcnt(cntp,cns,op1);
push(op1,st,sp); End;
End; (* of case *)
End; (* of this transform *)
If(tstr1='=') Then nextop(temp,tstr,sgp);
If(tstr[1]='[') Then
Begin
nextint(subp,sub,varn);
If(varn>dv) Then dv:=varn;
vars[varn]:=pop(st,sp);
If(tag=3) Then vars[varn]:=-1E37;
End;
If(tag=2) Then t:=1;
i:=i+1;
End;
End; (* Of transform *)
Begin (* main *)
openfiles(dfile,ofile,tfile,fo);
selectvar(sel,miss,nv,dv);
(* intialize *)
nt:=0; Randomize;
(* build transformations *)
If (fo=1) Then prmenu;
Writeln;
i:=1;
While i>0 Do
Begin
If(fo=1) Then
Begin
Writeln; Write(' ->');
Read(tfile,trans[i]);
End;
If(fo<>1) Then
Begin
Readln(tfile,trans[i]);
Writeln(' -> ',trans[i]);
End;
trans[i]:=Concat(trans[i],' ');
If (trans[i][1]='E') Then i:=0 Else i:=i+1;
End;
ParseNums(trans,cns,sub);
(* read and transform *)
k:=0;
For i:=1 To dv Do ho[i]:=-1E37;
While Not EOF(dfile) Do
Begin
k:=k+1;
getcase(vars,sel,nv,dv,dfile);
If (Frac(k/10)=0.0) Then Write('+');
If Not EOF(dfile) Then
Begin
transform(vars,ho,miss,cns,sub,dv,t,trans);
(* Output *)
If (t=0) Then Begin
For i:=1 To dv Do Write(usr,vars[i]:11,' '); Writeln(usr);
End;
End;
End;
Close(dfile); endwrite;
Assign(dfile,'MAPSTAT.COM'); Execute(dfile);
End.
0; Randomize;
(* build transformations *)
If (fo=1) Then prmenu;