unit SimultRegUnit; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons, Globals, MainUnit, MatrixLib, OutPutUnit, FunctionsLib, DataProcs; type { TSimultFrm } TSimultFrm = class(TForm) OpenDialog1: TOpenDialog; ResetBtn: TButton; CancelBtn: TButton; ComputeBtn: TButton; ReturnBtn: TButton; MatInChkBox: TCheckBox; MatSaveChkBox: TCheckBox; CPChkBox: TCheckBox; CovChkBox: TCheckBox; CorrsChkBox: TCheckBox; MeansChkBox: TCheckBox; SaveDialog1: TSaveDialog; VarChkBox: TCheckBox; SDChkBox: TCheckBox; InvMatChkBox: TCheckBox; GroupBox1: TGroupBox; InBtn: TBitBtn; OutBtn: TBitBtn; AllBtn: TBitBtn; Label1: TLabel; Label2: TLabel; ListBox1: TListBox; VarList: TListBox; procedure AllBtnClick(Sender: TObject); procedure ComputeBtnClick(Sender: TObject); procedure FormShow(Sender: TObject); procedure InBtnClick(Sender: TObject); procedure OutBtnClick(Sender: TObject); procedure ResetBtnClick(Sender: TObject); private { private declarations } public { public declarations } end; var SimultFrm: TSimultFrm; implementation { TSimultFrm } procedure TSimultFrm.ResetBtnClick(Sender: TObject); VAR i : integer; begin VarList.Clear; ListBox1.Clear; for i := 1 to NoVariables do begin VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); end; InBtn.Enabled := true; OutBtn.Enabled := false; CPChkBox.Checked := false; CovChkBox.Checked := false; CorrsChkBox.Checked := true; MeansChkBox.Checked := true; VarChkBox.Checked := false; SDChkBox.Checked := true; MatInChkBox.Checked := false; MatSaveChkBox.Checked := false; end; procedure TSimultFrm.FormShow(Sender: TObject); begin ResetBtnClick(Self); end; procedure TSimultFrm.AllBtnClick(Sender: TObject); VAR count, index : integer; begin count := VarList.Items.Count; for index := 0 to count-1 do begin ListBox1.Items.Add(VarList.Items.Strings[index]); end; VarList.Clear; end; procedure TSimultFrm.ComputeBtnClick(Sender: TObject); Label CleanUp; VAR NoVars, i, j, NCases, errcode, mattype : integer; StdErr, df1, df2, x, determinant : double; errorcode : boolean; filename : string; cellstring, outline, valstring : string; Corrs : DblDyneMat; Means : DblDyneVec; Variances : DblDyneVec; StdDevs : DblDyneVec; ColNoSelected : IntDyneVec; title : string; RowLabels : StrDyneVec; ColLabels : StrDyneVec; InverseMat : DblDyneMat; R2s : DblDyneVec; W : DblDyneVec; ProdMat : DblDyneMat; FProbs : DblDyneVec; CorrMat : DblDyneMat; begin SetLength(Corrs,NoVariables+1,NoVariables+1); SetLength(Means,NoVariables); SetLength(Variances,NoVariables); SetLength(StdDevs,NoVariables); SetLength(RowLabels,NoVariables); SetLength(ColLabels,NoVariables); SetLength(InverseMat,NoVariables,NoVariables); SetLength(R2s,NoVariables); SetLength(W,NoVariables); SetLength(ProdMat,NoVariables+1,NoVariables+1); SetLength(Fprobs,NoVariables); SetLength(CorrMat,NoVariables+1,NoVariables+1); SetLength(ColNoSelected,NoVariables); OutPutFrm.RichEdit.Clear; // OutPutFrm.RichEdit.ParaGraph.Alignment := taLeftJustify; OutPutFrm.RichEdit.Lines.Add('Simultaneous Multiple Regression by Bill Miller'); errcode := 0; if MatInChkBox.Checked = true then begin OpenDialog1.Filter := 'FreeStat matrix files (*.MAT)|*.MAT|All files (*.*)|*.*'; OpenDialog1.FilterIndex := 1; if OpenDialog1.Execute then begin filename := OpenDialog1.FileName; MATREAD(Corrs,NoVars,NoVars,Means,StdDevs,NCases,RowLabels,ColLabels,filename); for i := 1 to NoVars do Variances[i-1] := sqr(StdDevs[i-1]); ShowMessage('NOTICE! Last variable in matrix is the dependent variable'); end; end; if MatInChkBox.Checked = false then begin { get variable columns } NoVars := ListBox1.Items.Count; if NoVars < 1 then begin ShowMessage('ERROR! No variables selected.'); goto CleanUp; end; for i := 1 to NoVars do begin cellstring := ListBox1.Items.Strings[i-1]; for j := 1 to NoVariables do begin if cellstring = OS3MainFrm.DataGrid.Cells[j,0] then begin ColNoSelected[i-1] := j; RowLabels[i-1] := cellstring; ColLabels[i-1] := cellstring; end; end; end; end; if CPChkBox.Checked = true then begin title := 'Cross-Products Matrix'; GridXProd(NoVars,ColNoSelected,Corrs,errorcode,NCases); MAT_PRINT(Corrs,NoVars,NoVars,title,RowLabels,ColLabels,NCases); end; if CovChkBox.Checked = true then begin title := 'Variance-Covariance Matrix'; GridCovar(NoVars,ColNoSelected,Corrs,Means,Variances, StdDevs,errorcode,NCases); MAT_PRINT(Corrs,NoVars,NoVars,title,RowLabels,ColLabels,NCases); end; Correlations(NoVars,ColNoSelected,Corrs,Means,Variances, StdDevs,errorcode,NCases); if CorrsChkBox.Checked = true then for i := 1 to NoVars do for j := 1 to NoVars do InverseMat[i-1,j-1] := Corrs[i-1,j-1]; begin title := 'Product-Moment Correlations Matrix'; MAT_PRINT(Corrs,NoVars,NoVars,title,RowLabels,ColLabels,NCases); end; if MatSaveChkBox.Checked = true then begin SaveDialog1.Filter := 'OpenStat matrix files (*.MAT)|*.MAT|All files (*.*)|*.*'; SaveDialog1.FilterIndex := 1; if SaveDialog1.Execute then begin filename := SaveDialog1.FileName; MATSAVE(Corrs,NoVars,NoVars,Means,StdDevs,NCases,RowLabels,ColLabels,filename); end; end; title := 'Means'; if MeansChkBox.Checked = true then DynVectorPrint(Means,NoVars,title,ColLabels,NCases); title := 'Variances'; if VarChkBox.Checked = true then DynVectorPrint(Variances,NoVars,title,ColLabels,NCases); title := 'Standard Deviations'; if SDChkBox.Checked = true then DynVectorPrint(StdDevs,NoVars,title,ColLabels,NCases); if errcode > 0 then begin OutPutFrm.RichEdit.Lines.Add('One or more correlations could not be computed due to zero variance of a variable.'); end; if errcode > 0 then begin ShowMessage('ERROR! A selected variable has no variability-run aborted.'); goto CleanUp; end; determinant := 0.0; for i := 1 to NoVars do for j := 1 to NoVars do CorrMat[i-1,j-1] := Corrs[i-1,j-1]; Determ(CorrMat,NoVars,NoVars,determinant,errorcode); if (determinant < 0.000001) then begin ShowMessage('ERROR! Matrix is singular!'); goto cleanup; end; outline := format('Determinant of correlation matrix = %8.4f',[determinant]); OutPutFrm.RichEdit.Lines.Add(outline); OutPutFrm.RichEdit.Lines.Add(''); SVDinverse(InverseMat,NoVars); title := 'Inverse of correlation matrix'; if (InvMatChkBox.Checked = true) then MAT_PRINT(InverseMat,NoVars,NoVars,title,RowLabels,ColLabels,NCases); OutPutFrm.RichEdit.Lines.Add('Multiple Correlation Coefficients for Each Variable'); OutPutFrm.RichEdit.Lines.Add(''); outline := format('%10s%8s%10s%10s%12s%5s%5s',['Variable','R','R2','F','Prob.>F','DF1','DF2']); OutPutFrm.RichEdit.Lines.Add(outline); df1 := NoVars - 1.0; df2 := NCases - NoVars; for i := 1 to NoVars do begin // R squared values R2s[i-1] := 1.0 - (1.0 / InverseMat[i-1,i-1]); W[i-1] := (R2s[i-1] / df1) / ((1.0-R2s[i-1]) / df2); FProbs[i-1] := probf(W[i-1],df1,df2); valstring := format('%10s',[ColLabels[i-1]]); outline := format('%10s%10.3f%10.3f%10.3f%10.3f%5.0f%5.0f', [valstring,sqrt(R2s[i-1]),R2s[i-1],W[i-1],FProbs[i-1],df1,df2]); OutPutFrm.RichEdit.Lines.Add(outline); for j := 1 to NoVars do begin // betas ProdMat[i-1,j-1] := -InverseMat[i-1,j-1] / InverseMat[j-1,j-1]; end; end; title := 'Betas in Columns'; MAT_PRINT(ProdMat,NoVars,NoVars,title,RowLabels,ColLabels,NCases); OutPutFrm.RichEdit.Lines.Add('Standard Errors of Prediction'); OutPutFrm.RichEdit.Lines.Add('Variable Std.Error'); for i := 1 to NoVars do begin StdErr := (NCases-1) * Variances[i-1] * (1.0 / InverseMat[i-1,i-1]); StdErr := sqrt(StdErr / (NCases - NoVars)); valstring := format('%10s',[ColLabels[i-1]]); outline := format('%10s%10.3f',[valstring,StdErr]); OutPutFrm.RichEdit.Lines.Add(outline); end; for i := 1 to NoVars do for j := 1 to NoVars do if (i <> j) then ProdMat[i-1,j-1] := ProdMat[i-1,j-1] * (StdDevs[j-1]/StdDevs[i-1]); title := 'Raw Regression Coefficients'; MAT_PRINT(ProdMat,NoVars,NoVars,title,RowLabels,ColLabels,NCases); OutPutFrm.RichEdit.Lines.Add('Variable Constant'); for i := 1 to NoVars do begin x := 0.0; for j := 1 to NoVars do begin if (i <> j) then x := x + (ProdMat[j-1,i-1] * Means[j-1]); end; x := Means[i-1] - x; valstring := format('%10s',[ColLabels[i-1]]); outline := format('%10s%10.3f',[valstring,x]); OutPutFrm.RichEdit.Lines.Add(outline); end; // Get partial correlation matrix for i := 1 to NoVars do begin for j := 1 to NoVars do begin ProdMat[i-1,j-1] := -(1.0 / sqrt(InverseMat[i-1,i-1])) * InverseMat[i-1,j-1] * (1.0 / sqrt(InverseMat[j-1,j-1])); end; end; title := 'Partial Correlations'; MAT_PRINT(ProdMat,NoVars,NoVars,title,RowLabels,ColLabels,NCases); OutPutFrm.ShowModal; CleanUp: ColNoSelected := nil; CorrMat := nil; Fprobs := nil; ProdMat := nil; W := nil; R2s := nil; InverseMat := nil; ColLabels := nil; RowLabels := nil; StdDevs := nil; Variances := nil; Means := nil; corrs := nil; end; procedure TSimultFrm.InBtnClick(Sender: TObject); VAR i, index : integer; begin index := VarList.Items.Count; i := 0; while i < index do begin if (VarList.Selected[i]) then begin ListBox1.Items.Add(VarList.Items.Strings[i]); VarList.Items.Delete(i); index := index - 1; i := 0; end else i := i + 1; end; OutBtn.Enabled := true; end; procedure TSimultFrm.OutBtnClick(Sender: TObject); VAR index : integer; begin index := ListBox1.ItemIndex; VarList.Items.Add(ListBox1.Items.Strings[index]); ListBox1.Items.Delete(index); InBtn.Enabled := true; end; initialization {$I simultregunit.lrs} end.