home *** CD-ROM | disk | FTP | other *** search
- (* Multivariate Analysis Package - Principle Component Factoring 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 Factor(Input,Output);
- Type
- R35 = Array [1..35] Of Real;
- M35 = Array [1..35,1..35] Of Real;
- I35 = Array [1..35] Of Integer;
- S8 = Array [1..35] Of String[8];
- Var
- dfile, ofile : Text;
- sel : I35;
- e, u, v, w, x, y: R35;
- varn : S8;
- cor, a, vc : M35;
- i, j, k, nf, rn, nv, dv, ot, nc: Integer;
- temp : Real;
-
- Procedure openfiles(Var dfile, ofile:Text; Var nv, dv, ot:Integer);
- Var
- dfl, ofl:String[12];
- Begin
- ClrScr; Writeln(' *** FACTOR: PRINCIPLE COMPONENT FACTORING ***');
- Writeln; Write('Name of the CORREL file? ');
- Readln(dfl); Assign(dfile,dfl); Reset(dfile);
- Write('Name of the output file? ');
- Readln(ofl); Assign(ofile,ofl); Rewrite(ofile);
- ot:= 0;
- If (ofl='CON:') Or (ofl='con:') Then ot:=1;
- If (ofl='LST:') Or (ofl='lst:') Then ot:=2;
- If (ot=2) Then
- Begin
- Writeln(ofile,'Multivariate Analysis Package (1.2) - ',
- 'Program: FACTOR, Datafile: ',dfl); Writeln(ofile);
- End;
- Write('How many variables in CORREL matrix? ');
- Readln(nv);
- Write('Number of variables to use in FACTOR? ');
- Readln(dv);
- End; (* Of openfiles *)
-
- Procedure selectvar(Var sel:I35; Var varn:S8; dv:Integer);
- Var
- i:Integer;
- Begin
- Writeln;
- For i:=1 To dv Do
- Begin
- Write('Column number for variable ',i,'? ');
- Read(sel[i]); Write(' Name? '); Readln(varn[i]);
- End;
- End; (* Of selectvar *)
-
- Procedure wait(ot:Integer);
- Begin
- If ot=1 Then
- Begin
- Write('- Press any key to continue -'); While Not KeyPressed Do;
- ClrScr;
- End;
- End; (* of wait *)
-
- Procedure getcor(Var cor:M35; Var mean, stdev:R35; Var nc:Integer;
- sel:I35; nv, dv:Integer; Var dfile:Text);
- Var
- i,j,k,l,z:Integer;
- x,y:Real;
- dum15:String[15];
- dum21:String[21];
- dum8:String[8];
- dum36:String[36];
- Begin
- Readln(dfile); Readln(dfile);
- For i := 1 To nv Do
- Begin
- Readln(dfile,dum15,x,dum21,y,dum8,z);
- If (i=1) Then nc:=z;
- If (nc>z) Then nc:=z;
- For j := 1 To dv Do
- Begin
- If (sel[j]=i) Then
- Begin
- mean[j] := x; stdev[j] := y;
- End;
- End;
- End;
- For i :=1 to 3 Do Readln(dfile);
- For i := 1 To nv-1 Do
- For k := i+1 To nv Do
- Begin
- Readln(dfile,dum36,x,dum15,y);
- For j := 1 To dv Do
- Begin
- cor[j,j] := 1.0;
- If (sel[j]=i) Then
- For l := 1 To dv Do
- If (sel[l]=k) Then
- Begin
- cor[j,l] := y; cor[l,j] := y;
- End;
- End;
- End;
- End; (* Of getcor *)
-
- Procedure eigen(Var a, v:M35; Var e:R35; Var dv, nf, ot:Integer);
- (* eigenvalues and vectors by iteration and exhaustion - a is input
- matrix of dimension dv, nf the number of vectors to extract, e is
- returned eigenvalues and v is returned eigen vectors *)
- Var
- x,y:R35;
- j,k,l,it:Integer;
- t,s1,s2:Real;
- Begin
- l:=1; t:=0.00001;
- While (((dv-l)>0) and (l<=nf)) Do
- Begin
- it:=0; s1:=1.0;
- For j:=1 To dv Do y[j]:=1.0;
- While ((s1-t)>0.0) Do
- Begin
- it:=it+1;
- For j:=1 To dv Do
- Begin
- x[j]:=0.0;
- For k:=1 To dv Do x[j]:=x[j]+(a[j,k]*y[k]);
- End;
- e[l]:=x[1]; s1:=0.0;
- For j:=1 To dv Do
- Begin
- v[j,l]:=x[j]/x[1]; s1:=s1+(Abs(y[j]-v[j,l])); y[j]:=v[j,l];
- End;
- If ((it=20) and ((s2-s1)<=0)) Then Begin
- Writeln;
- Writeln('*** Roots Not Converging in Eigen - Error Abort ***');
- Bdos(0); End;
- s2:=s1;
- End;
- s1:=0.0;
- For j:=1 To dv Do s1:=s1+(v[j,l]*v[j,l]); s1:=Sqrt(s1);
- For j:=1 To dv Do v[j,l]:=v[j,l]/s1;
- For j:=1 To dv Do
- For k:=1 To dv Do a[j,k]:=a[j,k]-(v[j,l]*v[k,l]*e[l]);
- If(e[l]<1.0) Then
- Begin
- Writeln;
- nf:=l;
- Writeln('** Number of Eigenvalues Extracted Limited to ',nf:2,' **');
- Writeln('** Variance Explained by Factor too small For Accuracy **');
- wait(ot);
- End;
- l:=l+1;
- End;
- End; (* of eigen *)
-
- Procedure minv(Var a:M35; Var d:Real; m:Integer);
- (* matrix inversion in pascal: gauss - reduction method
- inverse returned in a and determinant in d, m is dimension *)
- Var
- j,k,l:Integer;
- pvt,t:Real;
- Begin
- d := 1.0;
- For j:=1 To m Do
- Begin
- pvt := a[j,j]; d := d*pvt; a[j,j] := 1.0;
- If (pvt=0) Then
- Begin
- Writeln; Writeln(' *** Multicollinear Matrix ***'); Writeln;
- End;
- For k:=1 To m Do a[j,k] := a[j,k]/pvt;
- For k:=1 To m Do
- If ((k-j) <> 0) Then
- Begin
- t := a[k,j]; a[k,j] := 0.0;
- For l:=1 To m Do a[k,l] := a[k,l] - (a[j,l]*t);
- End;
- End;
- End; (* of minv *)
-
- Procedure rotate(Var a:M35; nf, nv, meth, ot:Integer);
- Var
- c:R35;
- i,j,k,f,nr:Integer;
- ep,em,a1,b1,c1,d1,u,v,qn,qd,cs,sn,cs1,sn1,sp,cp:Real;
- Begin
- Writeln(ofile);
- If(meth=0) Then Writeln(ofile,'Varimax Rotation of ',nf:2,' Factors')
- Else Writeln(ofile,'Quartimax Rotation of ',nf:2,' Factors');
- ep:=0.00116;
- For j:=1 To nv Do
- Begin
- c[j]:=0.0;
- For k:=1 To nf Do c[j]:=c[j]+Sqr(a[j,k]);
- c[j]:=Sqrt(c[j]);
- For k:=1 To nf Do a[j,k]:=a[j,k]/c[j];
- End;
- While((nr-((nf*(nf-1))/2))<>0) Do
- Begin
- nr:=0;
- For i:=1 To (nf-1) Do
- Begin
- For j:=(I+1) To nf Do
- Begin
- a1:=0; b1:=0; c1:=0; d1:=0;
- For k:=1 to nv Do
- Begin
- u:=Sqr(a[k,i])-Sqr(a[k,j]); v:=a[k,i]*a[k,j]*2;
- a1:=a1+u; b1:=b1+v; c1:=c1+Sqr(u)-Sqr(v); d1:=d1+(u*v*2);
- End;
- If(meth=1) Then
- Begin
- qn:=d1-((2*a1*b1)/nv); qd:=c1-((Sqr(a1)-Sqr(b1))/nv);
- End;
- If(meth=0) Then
- Begin
- qn:=d1; qd:=c1;
- End;
- f:=0;
- If((Abs(qn)+Abs(qd))<1) Then
- Begin
- nr:=nr+1; f:=1;
- End;
- If((Abs(qn)-Abs(qd))=0) Then
- Begin
- cs:=0.70710678; sn:=cs; f:=2;
- End;
- If((Abs(qn)-Abs(qd))>1) Then
- Begin
- em:=Abs(qd/qn);
- If((em-ep)>=0) Then
- Begin
- cs:=0; sn:=1;
- End
- Else
- Begin
- sn:=1/Sqrt(1+Sqr(em)); cs:=sn*em;
- End;
- f:=2;
- End;
- If(f=0) Then
- Begin
- em:=Abs(qn/qd);
- If((em-ep)>=0) Then
- Begin
- cs:=Cos(ArcTan(em)); sn:=Sin(ArcTan(em)); f:=2;
- End
- Else
- If(qd>=0) Then
- Begin
- nr:=nr+1; f:=1;
- End
- Else
- Begin
- sp:=0.70710678; cp:=sp; f:=3;
- End
- End;
- If(f=2) Then
- Begin
- em:=Sqrt((1+cs)*0.5); cs1:=Sqrt((1+em)*0.5); sn1:=sn/(4*cs1*em);
- If(qd<0) Then
- Begin
- cp:=0.70710678*(cs1+sn1); sp:=0.70710678*(cs1-sn1);
- End
- Else
- Begin
- cp:=cs1; sp:=sn1;
- End;
- If(qn<0) Then sp:=-sp;
- End;
- If((f=2) or (f=3)) Then
- For k:=1 To nv Do
- Begin
- em:=(a[k,i]*cp)-(a[k,j]*sp);
- a[k,j]:=(a[k,j]*cp)-(a[k,i]*sp);
- a[k,i]:=em;
- End;
- End;
- End;
- End;
- For i:=1 To nv Do
- For j:=1 To nf Do a[i,j]:=a[i,j]*c[i];
- For j:=1 To nf Do
- Begin
- c[j]:=0;
- For k:=1 To nv Do c[j]:=c[j]+Sqr(a[k,j]);;
- End;
- em:=nv;
- For j:=1 To nv Do c[j]:=c[j]/nv;
- ClrScr;
- For i:=1 To nf Do
- Begin
- Writeln(ofile); Writeln(ofile,'Rotated Factor Pattern For Factor: ',i:2);
- For j:=1 To dv Do
- Begin
- Writeln(ofile,' ',varn[j]:8,': ',a[i,j]:12);
- End;
- Writeln(ofile,'Factor Accounts For ',(c[i]*100):8:5,'% of Variance');
- wait(ot);
- End;
- End; (* of rotate *)
-
- Begin (* main *)
- openfiles(dfile, ofile, nv, dv, ot);
- Write('Number of Factors to Extract (<=number of variables)? ');
- Readln(nf); If (nf=dv) Then rn:=0 Else rn:=1;
- selectvar(sel, varn, dv);
- (* read correlation matrix matrix *)
- getcor(cor, x, y, nc, sel, nv, dv, dfile);
- (* full rank analysis *)
- If(rn=0) Then
- Begin
- For i:=1 To dv Do For j:=1 To dv Do a[i,j]:=cor[i,j];
- (* invert *)
- minv(a,temp,dv);
- temp:=-((nc-1.0)-((1.0/6.0)*(2.0*nc+5.0)))*Ln(temp);
- ClrScr;
- Writeln(ofile);
- Write(ofile,'Chi-Square for Sphericity = ',temp:10:3);
- Writeln(ofile,' degrees of freedom = ',((Sqr(dv)-dv)/2):6:0);
- wait(ot);
- For j:=1 To dv Do w[j]:=1.0-(1.0/a[j,j]);
- End;
- eigen(cor, vc, e, dv, nf, ot);
- temp:=0.0;
- For j:=1 To nf Do
- Begin
- u[j]:=(e[j]/dv)*100; temp:=temp+u[j]; v[j]:=temp;
- For k:=1 To dv Do
- Begin
- a[k,j]:=cor[k,j]*(1/Sqr(e[j]));; cor[k,j]:=cor[k,j]*Sqr(e[j]);
- End;
- End;
- ClrScr; Writeln(ofile);
- Writeln(ofile,'Factor Eigen %Variance %Cumulative');
- Writeln(ofile);
- For i:=1 To nf Do Writeln(ofile,' ',i:2,' ',e[i]:8:5,
- ' ',u[i]:7:3,' ',v[i]:7:3);
- Writeln(ofile);
- wait(ot);
- For i:=1 To nf Do
- Begin
- Writeln(ofile); Writeln(ofile,'Factor Pattern For Factor: ',i:2);
- For j:=1 To dv Do
- Begin
- Writeln(ofile,' ',varn[j]:8,': ',cor[i,j]:12);
- End;
- wait(ot);
- End;
- Writeln(ofile); Write(ofile,'Variable Communality');
- If(rn=0) Then Writeln(ofile,' R-Square') Else Writeln(ofile);
- For j:=1 To dv Do
- Begin
- temp:=0.0;
- For k:=1 To nf Do temp:=temp+Sqr(cor[j,k]);
- Write(ofile,' ',varn[j]:8,' ',temp:10:7);
- If(rn=0) Then Writeln(ofile,' ',w[j]:10:7) Else Writeln(ofile);
- End;
- wait(ot);
- For i:=1 To nf Do
- Begin
- Writeln(ofile); Writeln(ofile,'Score Coefficients For Factor: ',i:2);
- For j:=1 To dv Do
- Begin
- Writeln(ofile,' ',varn[j]:8,': ',a[i,j]:12);
- End;
- wait(ot);
- End;
- If(nf>1) Then
- Begin
- Write('What type of Factor Rotation (0=none,1=varimax,2=quartimax)?');
- Readln(i); i:=i-1; If(i>=0) Then rotate(cor, nf, dv, i, ot);
- End;
- Close(ofile); Close(dfile);
- End.
- ▌~ ═W╓08)■
- 8
- !╓■
- 8■0T])╪)╪
- T]╪)╪_ ╪╦y╖╚|ç╔▌ßßσ}&