From a7c0827825e1d47c9a9bcb95fa4231ca58c1f7c5 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Fri, 10 Apr 2020 15:30:19 +0000 Subject: [PATCH] LazStats: Refactor PathUnit in the usual way. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7367 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../lazstats/docs/HelpNDoc/LazStats.hnd | Bin 5738496 -> 5795840 bytes .../analysis/multivariate/factorunit.pas | 3 - .../forms/analysis/multivariate/pathunit.lfm | 95 +- .../forms/analysis/multivariate/pathunit.pas | 1114 +++++++++-------- .../lazstats/source/units/globals.pas | 2 + 5 files changed, 624 insertions(+), 590 deletions(-) diff --git a/applications/lazstats/docs/HelpNDoc/LazStats.hnd b/applications/lazstats/docs/HelpNDoc/LazStats.hnd index d3f08e8c3d27802f5aa8e603f2f04daa8b475962..c03e78b536fc8e8439a8d2b0c32cf535b0560a30 100644 GIT binary patch delta 24755 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 delta 1177 zcmWmDZA@EL7zglk?z!*u-V2PufDLX-i?oGN-d4(Z>BayDtJE<{#6`L-zU%`UT*6{7 zu51Z6(QGSJIA4$<(`0@iG;?}bG6OL)V$^IVQxTI1&MZ-u1trl5G5GM|_u=Gul5@_J z=O0^M;bN2bxp=N{5+UJ@VY30B9E^Sv#UI?sl#C^W5Z`TV8h;yq8jp;J#RpXD-!ZFNlkML^>yK#gIKad;sei`a7QJaqpLAehzQcikp zH0cpV)?ZI9Ve$g5pi+>u&~T7^mN3Ibyo-c5YOX6L>pDPY9`jLzqEz+q6;ykS)9D}6 z_B3hYAQAI#Rj?|P*Clq;&ug4@KEMM3h(H1|J0DQSZep2buPduIoI5J0u1uvv@yL@>MtO$Lby0*1+$ikf|NgKy~au>?M{w|vA!~tv=1d6L&<_qlTJPrpP<6LbCizHJAEAaf_*dZ zJT2j`=<@7-lSUSt=Vm+~cXlVvK!3tMz~ zRQg;gkOp8jZwoRz9xtpTiTFi>Uh5zMYb8+#o&rU{%~legg5$W03TvKs=*XIX{ZvOFx#i2H;&p_%`hKSqAWm&mKq6~j_{xPRnb+*_Pvr0P`9(>_8In$I?C zYmkak7E;>PMVysL3rFbXWU);3v8EvPZDj9d17+pE$uLUvGM!H0PFX!Q<)8vof-0~N z_(3%YfEutL)Pg!t4;nxa8~_JFBRB+_Kr?6oPlLm(r>6Bo7p|p3v^APLE40gxbW_a` z&!T^EqcI|mD{1&gd>vn;v1M+GIZm{WVf-$&zptD0r(d}?o+MB!?VHw3((NQPZ(VV) z-czmg7D>nVsARS|@jXb{HJmf(Ihz%NUG~D?5RwsgV;O4|D1^3y)lBVn3x>BF`H% OHq&*1k$B|4t^WbzYKH~@ diff --git a/applications/lazstats/source/forms/analysis/multivariate/factorunit.pas b/applications/lazstats/source/forms/analysis/multivariate/factorunit.pas index 5db4daf7a..c96f3cf8e 100644 --- a/applications/lazstats/source/forms/analysis/multivariate/factorunit.pas +++ b/applications/lazstats/source/forms/analysis/multivariate/factorunit.pas @@ -105,9 +105,6 @@ implementation uses Math, Utils, RotateUnit; -const - DIVIDER = '========================================================================'; - { TFactorFrm } procedure TFactorFrm.ResetBtnClick(Sender: TObject); diff --git a/applications/lazstats/source/forms/analysis/multivariate/pathunit.lfm b/applications/lazstats/source/forms/analysis/multivariate/pathunit.lfm index 0a7d09c6c..ff0377d36 100644 --- a/applications/lazstats/source/forms/analysis/multivariate/pathunit.lfm +++ b/applications/lazstats/source/forms/analysis/multivariate/pathunit.lfm @@ -66,85 +66,65 @@ object PathFrm: TPathFrm end end object ResetBtn: TButton - AnchorSideRight.Control = CancelBtn + AnchorSideRight.Control = ComputeBtn AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 290 + Left = 382 Height = 25 Top = 354 Width = 54 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'Reset' OnClick = ResetBtnClick TabOrder = 3 end - object CancelBtn: TButton - AnchorSideRight.Control = ComputeBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 356 - Height = 25 - Top = 354 - Width = 62 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 12 - BorderSpacing.Top = 8 - BorderSpacing.Right = 12 - BorderSpacing.Bottom = 8 - Caption = 'Cancel' - ModalResult = 2 - OnClick = CancelBtnClick - TabOrder = 4 - end object ComputeBtn: TButton - AnchorSideRight.Control = ReturnBtn + AnchorSideRight.Control = CloseBtn AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 430 + Left = 444 Height = 25 Top = 354 Width = 76 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'Compute' OnClick = ComputeBtnClick - TabOrder = 5 + TabOrder = 4 end - object ReturnBtn: TButton + object CloseBtn: TButton AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 518 + Left = 528 Height = 25 Top = 354 - Width = 61 + Width = 55 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 - Caption = 'Return' - ModalResult = 1 - OnClick = ReturnBtnClick - TabOrder = 6 + Caption = 'Close' + ModalResult = 11 + TabOrder = 5 end object Bevel1: TBevel AnchorSideLeft.Control = Owner AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = ReturnBtn + AnchorSideBottom.Control = CloseBtn Left = 0 Height = 8 Top = 338 @@ -223,6 +203,7 @@ object PathFrm: TPathFrm BorderSpacing.Right = 8 ItemHeight = 0 MultiSelect = True + OnSelectionChange = ListBox1SelectionChange TabOrder = 0 end object InBtn: TBitBtn @@ -273,15 +254,17 @@ object PathFrm: TPathFrm BorderSpacing.Top = 2 ItemHeight = 0 MultiSelect = True + OnSelectionChange = ListBox1SelectionChange TabOrder = 3 end end object Label3: TLabel - AnchorSideTop.Control = Owner + AnchorSideTop.Control = ModelNo + AnchorSideTop.Side = asrCenter AnchorSideRight.Control = ModelNo Left = 446 Height = 15 - Top = 8 + Top = 12 Width = 84 Anchors = [akTop, akRight] BorderSpacing.Top = 10 @@ -296,7 +279,7 @@ object PathFrm: TPathFrm AnchorSideBottom.Control = CausedEdit Left = 457 Height = 15 - Top = 69 + Top = 73 Width = 93 BorderSpacing.Top = 16 BorderSpacing.Bottom = 2 @@ -309,24 +292,25 @@ object PathFrm: TPathFrm AnchorSideTop.Side = asrBottom Left = 457 Height = 15 - Top = 149 + Top = 153 Width = 102 BorderSpacing.Top = 40 Caption = '"Causing" Variables' ParentColor = False end object ModelNo: TEdit - AnchorSideTop.Control = Label3 - AnchorSideTop.Side = asrCenter + AnchorSideTop.Control = Panel2 AnchorSideRight.Control = Panel2 AnchorSideRight.Side = asrBottom Left = 538 Height = 23 - Top = 4 + Top = 8 Width = 45 Alignment = taRightJustify Anchors = [akTop, akRight] + BorderSpacing.Top = 8 BorderSpacing.Right = 8 + ReadOnly = True TabOrder = 1 Text = 'ModelNo' end @@ -338,12 +322,14 @@ object PathFrm: TPathFrm AnchorSideRight.Side = asrBottom Left = 457 Height = 22 - Top = 31 + Top = 35 Width = 126 Anchors = [akTop, akLeft, akRight] BorderSpacing.Top = 4 BorderSpacing.Right = 8 + Min = 1 PageSize = 0 + Position = 1 TabOrder = 2 OnChange = ScrollBarChange end @@ -357,13 +343,14 @@ object PathFrm: TPathFrm AnchorSideBottom.Side = asrBottom Left = 457 Height = 23 - Top = 86 + Top = 90 Width = 126 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 8 BorderSpacing.Top = 2 BorderSpacing.Right = 8 BorderSpacing.Bottom = 12 + ReadOnly = True TabOrder = 5 Text = 'CausedEdit' end @@ -377,8 +364,8 @@ object PathFrm: TPathFrm AnchorSideBottom.Control = Panel2 AnchorSideBottom.Side = asrBottom Left = 457 - Height = 92 - Top = 166 + Height = 88 + Top = 170 Width = 126 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Left = 8 @@ -386,6 +373,8 @@ object PathFrm: TPathFrm BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 ItemHeight = 0 + MultiSelect = True + OnSelectionChange = ListBox1SelectionChange TabOrder = 8 end object CausedInBtn: TBitBtn @@ -395,7 +384,7 @@ object PathFrm: TPathFrm AnchorSideBottom.Control = CausedOutBtn Left = 421 Height = 28 - Top = 58 + Top = 62 Width = 28 Anchors = [akBottom] BorderSpacing.Left = 8 @@ -413,7 +402,7 @@ object PathFrm: TPathFrm AnchorSideBottom.Side = asrBottom Left = 421 Height = 28 - Top = 88 + Top = 92 Width = 28 BorderSpacing.Top = 2 BorderSpacing.Bottom = 3 @@ -429,7 +418,7 @@ object PathFrm: TPathFrm AnchorSideTop.Control = CausingList Left = 421 Height = 28 - Top = 166 + Top = 170 Width = 28 BorderSpacing.Left = 8 Images = MainDataModule.ImageList @@ -444,7 +433,7 @@ object PathFrm: TPathFrm AnchorSideTop.Side = asrBottom Left = 421 Height = 28 - Top = 198 + Top = 202 Width = 28 BorderSpacing.Top = 4 Images = MainDataModule.ImageList diff --git a/applications/lazstats/source/forms/analysis/multivariate/pathunit.pas b/applications/lazstats/source/forms/analysis/multivariate/pathunit.pas index b72f34e1b..6117b455a 100644 --- a/applications/lazstats/source/forms/analysis/multivariate/pathunit.pas +++ b/applications/lazstats/source/forms/analysis/multivariate/pathunit.pas @@ -1,3 +1,8 @@ +// Sample file for testing: cansas.laz, +// all variables to center list, +// waist --> caused variables +// weight --> causing variables + unit PathUnit; {$mode objfpc}{$H+} @@ -19,9 +24,8 @@ type Panel2: TPanel; Panel3: TPanel; ResetBtn: TButton; - CancelBtn: TButton; ComputeBtn: TButton; - ReturnBtn: TButton; + CloseBtn: TButton; SaveDialog1: TSaveDialog; StatsChk: TCheckBox; ModelChk: TCheckBox; @@ -46,7 +50,6 @@ type VarList: TListBox; ScrollBar: TScrollBar; ListBox1: TListBox; - procedure CancelBtnClick(Sender: TObject); procedure CausedInBtnClick(Sender: TObject); procedure CausedOutBtnClick(Sender: TObject); procedure CausingInBtnClick(Sender: TObject); @@ -56,20 +59,21 @@ type procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure InBtnClick(Sender: TObject); + procedure ListBox1SelectionChange(Sender: TObject; User: boolean); procedure OutBtnClick(Sender: TObject); procedure ResetBtnClick(Sender: TObject); procedure ResetModelBtnClick(Sender: TObject); - procedure ReturnBtnClick(Sender: TObject); procedure ScrollBarChange(Sender: TObject); private { private declarations } FAutoSized: Boolean; - Model : integer; - ModelDefined : BoolDyneVec; - causedseq : IntDyneVec; - nocausing : IntDyneVec; - causingseq : IntDyneMat; - NoModels : integer; + Model: integer; + ModelDefined: BoolDyneVec; + causedseq: IntDyneVec; + nocausing: IntDyneVec; + causingseq: IntDyneMat; + NoModels: integer; + procedure UpdateBtnStates; public { public declarations } end; @@ -80,58 +84,47 @@ var implementation uses - Math; + Math, Utils; { TPathFrm } procedure TPathFrm.ResetBtnClick(Sender: TObject); -VAR i : integer; +var + i: integer; begin - if causingseq = nil then SetLength(causingseq,NoVariables,NoVariables); - if ModelDefined = nil then SetLength(ModelDefined,NoVariables); - if nocausing = nil then SetLength(nocausing,NoVariables); - if causedseq = nil then SetLength(causedseq,NoVariables); - ListBox1.Clear; - CausingList.Clear; - VarList.Clear; - OutBtn.Enabled := false; - InBtn.Enabled := true; - CausedOutBtn.Enabled := false; - CausedInBtn.Enabled := true; - CausingInBtn.Enabled := true; - CausingOutBtn.Enabled := false; - ModelNo.Text := '1'; - ScrollBar.Position := 1; - CausedEdit.Text := ''; - StatsChk.Checked := true; - ModelChk.Checked := true; - ReproChk.Checked := true; - SaveChk.Checked := false; - NoModels := 0; - for i := 1 to NoVariables do - ListBox1.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); - for i := 1 to NoVariables do ModelDefined[i-1] := false; + SetLength(causingseq,NoVariables,NoVariables); + SetLength(ModelDefined,NoVariables); + SetLength(nocausing,NoVariables); + SetLength(causedseq,NoVariables); + ListBox1.Clear; + CausingList.Clear; + VarList.Clear; + ModelNo.Text := '1'; + ScrollBar.Position := 1; + CausedEdit.Text := ''; + StatsChk.Checked := true; + ModelChk.Checked := true; + ReproChk.Checked := true; + SaveChk.Checked := false; + NoModels := 0; + for i := 1 to NoVariables do + ListBox1.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); + for i := 1 to NoVariables do + ModelDefined[i-1] := false; + UpdateBtnStates; end; procedure TPathFrm.ResetModelBtnClick(Sender: TObject); -VAR i : integer; +var + i: integer; begin - Model := ScrollBar.Position; - if CausedEdit.Text <> '' then CausedOutBtnClick(self); - if CausingList.Items.Count > 0 then CausingList.Clear; - causedseq[Model-1] := 0; - nocausing[Model-1] := 0; - for i := 1 to nocausing[Model-1] do causingseq[Model-1,i-1] := 0; - ModelDefined[Model-1] := false; -end; - -procedure TPathFrm.ReturnBtnClick(Sender: TObject); -begin - causedseq := nil; - nocausing := nil; - causingseq := nil; - ModelDefined := nil; - Close; + Model := ScrollBar.Position; + if CausedEdit.Text <> '' then CausedOutBtnClick(self); + if CausingList.Items.Count > 0 then CausingList.Clear; + causedseq[Model-1] := 0; + nocausing[Model-1] := 0; + for i := 1 to nocausing[Model-1] do causingseq[Model-1,i-1] := 0; + ModelDefined[Model-1] := false; end; procedure TPathFrm.ScrollBarChange(Sender: TObject); @@ -209,11 +202,10 @@ begin if FAutoSized then exit; - w := MaxValue([ResetBtn.Width, CancelBtn.Width, ComputeBtn.Width, ReturnBtn.Width]); + w := MaxValue([ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]); ResetBtn.Constraints.MinWidth := w; - CancelBtn.Constraints.MinWidth := w; ComputeBtn.Constraints.MinWidth := w; - ReturnBtn.Constraints.MinWidth := w; + CloseBtn.Constraints.MinWidth := w; Constraints.MinWidth := Width; Constraints.MinHeight := Height; @@ -223,39 +215,59 @@ end; procedure TPathFrm.FormCreate(Sender: TObject); begin Assert(OS3MainFrm <> nil); - if OutputFrm = nil then - Application.CreateForm(TOutputFrm, OutputFrm); end; procedure TPathFrm.FormShow(Sender: TObject); begin - causedseq := nil; - nocausing := nil; - causingseq := nil; - ModelDefined := nil; - ResetBtnClick(self); + causedseq := nil; + nocausing := nil; + causingseq := nil; + ModelDefined := nil; + ResetBtnClick(self); end; procedure TPathFrm.InBtnClick(Sender: TObject); -VAR i, index : integer; +var + i: integer; begin - index := ListBox1.Items.Count; - i := 0; - while i < index do - begin - if (ListBox1.Selected[i]) then - begin - VarList.Items.Add(ListBox1.Items.Strings[i]); - ListBox1.Items.Delete(i); - index := index - 1; - i := 0; - end - else i := i + 1; - end; - OutBtn.Enabled := true; + i := 0; + while i < ListBox1.Items.Count do + begin + if ListBox1.Selected[i] then + begin + VarList.Items.Add(ListBox1.Items[i]); + ListBox1.Items.Delete(i); + i := 0; + end else + i := i + 1; + end; + UpdateBtnStates; +end; + +procedure TPathFrm.ListBox1SelectionChange(Sender: TObject; User: boolean); +begin + UpdateBtnStates; end; procedure TPathFrm.OutBtnClick(Sender: TObject); +var + i: integer; +begin + i := 0; + while i < VarList.Items.Count do + begin + if VarList.Selected[i] then + begin + ListBox1.Items.Add(VarList.Items[i]); + VarList.Items.Delete(i); + i := 0; + end else + i := i + 1; + end; + UpdateBtnStates; +end; + + (* VAR index : integer; begin index := VarList.ItemIndex; @@ -265,55 +277,49 @@ begin exit; end; VarList.Items.Delete(index); -end; - -procedure TPathFrm.CancelBtnClick(Sender: TObject); -begin - causedseq := nil; - nocausing := nil; - causingseq := nil; - ModelDefined := nil; - Close; -end; +end; *) procedure TPathFrm.CausedInBtnClick(Sender: TObject); -VAR index : integer; +var + index: integer; begin - index := VarList.ItemIndex; - CausedEdit.Text := VarList.Items.Strings[index]; - CausedOutBtn.Enabled := true; - CausedInBtn.Enabled := false; + index := VarList.ItemIndex; + if (index > -1) and (CausedEdit.Text = '') then + begin + CausedEdit.Text := VarList.Items[index]; + CausedOutBtn.Enabled := true; + CausedInBtn.Enabled := false; + end; + UpdateBtnStates; end; procedure TPathFrm.CausedOutBtnClick(Sender: TObject); begin - CausedEdit.Text := ''; - CausedOutBtn.Enabled := false; - CausedInBtn.Enabled := true; + if CausedEdit.Text <> '' then + CausedEdit.Text := ''; + UpdateBtnStates; end; procedure TPathFrm.CausingInBtnClick(Sender: TObject); -VAR i, index : integer; +var + i: integer; begin - index := VarList.Items.Count; - for i := 0 to index-1 do - begin - if (VarList.Selected[i]) then - CausingList.Items.Add(VarList.Items.Strings[i]); - end; - CausingOutBtn.Enabled := true; + for i := 0 to VarList.Items.Count-1 do + begin + if VarList.Selected[i] then + CausingList.Items.Add(VarList.Items[i]); + end; + UpdateBtnStates; end; procedure TPathFrm.CausingOutBtnClick(Sender: TObject); -VAR index : integer; +var + index: integer; begin - index := CausingList.ItemIndex; - if index < 0 then - begin - CausingOutBtn.Enabled := false; - exit; - end; - CausingList.Items.Delete(index); + index := CausingList.ItemIndex; + if index > -1 then + CausingList.Items.Delete(index); + UpdateBtnStates; end; procedure TPathFrm.ComputeBtnClick(Sender: TObject); @@ -321,7 +327,7 @@ var i, j, k, col, row, NoVars, nocaused, NoSelected, NoIndepVars : integer; count, IER, noexogenous, t, L: integer; constant, StdErrEst, ProbOut, R2, Temp, d2, sum, absdiff : double; - cellstring, outline : string; + cellstring: string; ColNoSelected, selected : IntDyneVec; IndepIndex : IntDyneVec; rmat, WorkMat, PathCoef, IndMatrix, InvMatrix, e, W : DblDyneMat; @@ -337,473 +343,513 @@ var errorcode : boolean = false; done : boolean; zscore : double; + lReport: TStrings; begin - if NoModels < ScrollBar.Position then - begin - Model := ScrollBar.Position; - ModelDefined[Model-1] := true; - nocausing[Model-1] := CausingList.Items.Count; - NoModels := NoModels + 1; - for i := 1 to NoVariables do + if CausedEdit.Text = '' then + begin + MessageDlg('No "Caused" variable selected.', mtError, [mbOK], 0); + exit; + end; + + if CausingList.Items.Count = 0 then + begin + MessageDlg('No "Causing" variable(s) selected.',mtError, [mbOK], 0); + exit; + end; + + if NoModels < ScrollBar.Position then + begin + Model := ScrollBar.Position; + ModelDefined[Model-1] := true; + nocausing[Model-1] := CausingList.Items.Count; + NoModels := NoModels + 1; + for i := 1 to NoVariables do + begin + cellstring := OS3MainFrm.DataGrid.Cells[i,0]; + if cellstring = CausedEdit.Text then causedseq[Model-1] := i; + for j := 0 to CausingList.Items.Count - 1 do + begin + if cellstring = CausingList.Items.Strings[j] then + causingseq[Model-1,j] := i; + end; + end; + CausingList.Clear; + CausedEdit.Text := ''; + CausedInBtn.Enabled := true; + CausedOutBtn.Enabled := false; + CausingInBtn.Enabled := true; + CausingOutBtn.Enabled := false; + end; + + nocaused := NoModels; + SetLength(rmat,NoVariables+1,NoVariables+1); + SetLength(WorkMat,NoVariables+1,NoVariables+1); + SetLength(PathCoef,NoVariables,NoVariables); + SetLength(IndMatrix,NoVariables,NoVariables); + SetLength(InvMatrix,NoVariables,NoVariables); + SetLength(e,NoVariables,NoVariables); + SetLength(W,NoVariables,NoVariables); + SetLength(means,NoVariables); + SetLength(variances,NoVariables); + SetLength(stddevs,NoVariables); + SetLength(beta,NoVariables); + SetLength(p,NoVariables*NoVariables); + SetLength(Causal,2,NoVariables*NoVariables); + SetLength(RowLabels,NoCases); + SetLength(ColLabels,NoVariables); + SetLength(Labels,NoVariables); + SetLength(IndepIndex,NoVariables); + SetLength(exogenous,NoVariables); + SetLength(ColNoSelected,NoVariables); + SetLength(selected,NoVariables); + SetLength(zvals,NoCases,NoVariables); + SetLength(genedz,NoVariables); + + // get and show model parameters + lReport := TStringList.Create; + try + lReport.Add('PATH ANALYSIS RESULTS'); + lReport.Add(''); + + for i := 1 to nocaused do + begin + col := causedseq[i-1]; + lReport.Add('CAUSED VARIABLE: ' + OS3MainFrm.DataGrid.Cells[col,0]); + lReport.Add(' Causing Variables:'); + for j := 1 to nocausing[i-1] do + begin + col := causingseq[i-1,j-1]; + lReport.Add(' ' + OS3MainFrm.DataGrid.Cells[col,0]); + end; + end; + lReport.Add(''); + lReport.Add(DIVIDER); + lReport.Add(''); + + // get correlations among all variables selected for the analysis + NoSelected := VarList.Items.Count; + for j := 1 to NoVariables do + begin + cellstring := OS3MainFrm.DataGrid.Cells[j,0]; + for i := 1 to NoSelected do + begin + if cellstring = VarList.Items.Strings[i-1] then begin - cellstring := OS3MainFrm.DataGrid.Cells[i,0]; - if cellstring = CausedEdit.Text then causedseq[Model-1] := i; - for j := 0 to CausingList.Items.Count - 1 do - begin - if cellstring = CausingList.Items.Strings[j] then - causingseq[Model-1,j] := i; - end; + ColNoSelected[i-1] := j; + RowLabels[i-1] := cellstring; end; - CausingList.Clear; - CausedEdit.Text := ''; - CausedInBtn.Enabled := true; - CausedOutBtn.Enabled := false; - CausingInBtn.Enabled := true; - CausingOutBtn.Enabled := false; - end; + end; + end; - nocaused := NoModels; - SetLength(rmat,NoVariables+1,NoVariables+1); - SetLength(WorkMat,NoVariables+1,NoVariables+1); - SetLength(PathCoef,NoVariables,NoVariables); - SetLength(IndMatrix,NoVariables,NoVariables); - SetLength(InvMatrix,NoVariables,NoVariables); - SetLength(e,NoVariables,NoVariables); - SetLength(W,NoVariables,NoVariables); - SetLength(means,NoVariables); - SetLength(variances,NoVariables); - SetLength(stddevs,NoVariables); - SetLength(beta,NoVariables); - SetLength(p,NoVariables*NoVariables); - SetLength(Causal,2,NoVariables*NoVariables); - SetLength(RowLabels,NoCases); - SetLength(ColLabels,NoVariables); - SetLength(Labels,NoVariables); - SetLength(IndepIndex,NoVariables); - SetLength(exogenous,NoVariables); - SetLength(ColNoSelected,NoVariables); - SetLength(selected,NoVariables); - SetLength(zvals,NoCases,NoVariables); - SetLength(genedz,NoVariables); + count := NoCases; + Correlations(NoSelected,ColNoSelected,rmat,means,variances,stddevs, errorcode,count); + if SaveChk.Checked then + begin + SaveDialog1.Filter := 'Matrix files (*.mat)|*.mat;*.MAT|All files (*.*)|*.*'; + SaveDialog1.FilterIndex := 1; + if SaveDialog1.Execute then + MatSave(rmat, NoSelected, NoSelected, means, stddevs, count, RowLabels, RowLabels,SaveDialog1.FileName); + end; - // get and show model parameters - OutputFrm.RichEdit.Clear; - OutputFrm.RichEdit.Lines.Add('PATH ANALYSIS RESULTS'); - OutputFrm.RichEdit.Lines.Add(''); + if StatsChk.Checked then + begin + title := 'Correlation Matrix'; + MatPrint(rmat, NoSelected, NoSelected, title, RowLabels, RowLabels, count, lReport); - for i := 1 to nocaused do - begin - col := causedseq[i-1]; - outline := 'CAUSED VARIABLE: '; - outline := outline + OS3MainFrm.DataGrid.Cells[col,0]; - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(' Causing Variables:'); - for j := 1 to nocausing[i-1] do - begin - col := causingseq[i-1,j-1]; - outline := ' '; - outline := outline + OS3MainFrm.DataGrid.Cells[col,0]; - OutputFrm.RichEdit.Lines.Add(outline); - end; - end; - OutputFrm.ShowModal; - OutputFrm.RichEdit.Clear; + title := 'MEANS'; + DynVectorPrint(means, NoSelected, title, RowLabels, count, lReport); - // get correlations among all variables selected for the analysis - NoSelected := VarList.Items.Count; - for j := 1 to NoVariables do - begin - cellstring := OS3MainFrm.DataGrid.Cells[j,0]; - for i := 1 to NoSelected do - begin - if cellstring = VarList.Items.Strings[i-1] then - begin - ColNoSelected[i-1] := j; - RowLabels[i-1] := cellstring; - end; - end; - end; - count := NoCases; - Correlations(NoSelected,ColNoSelected,rmat,means,variances,stddevs, errorcode,count); - if SaveChk.Checked then - begin - SaveDialog1.Filter := 'Matrix files (*.MAT)|*.MAT|All files (*.*)|*.*'; - SaveDialog1.FilterIndex := 1; - SaveDialog1.Execute; - MATSAVE(rmat,NoSelected,NoSelected,means,stddevs,count,RowLabels, - RowLabels,SaveDialog1.FileName); - end; + title := 'VARIANCES'; + DynVectorPrint(variances, NoSelected, title, RowLabels, count, lReport); - if StatsChk.Checked then - begin + title := 'STANDARD DEVIATIONS'; + DynVectorPrint(stddevs, NoSelected, title, RowLabels, count, lReport); + + lReport.Add(DIVIDER); + lReport.Add(''); + end; + + // initialize reconstruction matrix, weights matrix and path coefficients + for i := 0 to NoSelected-1 do + begin + for j := 0 to NoSelected-1 do + begin + e[i,j] := 0.0; + W[i,j] := 0.0; + PathCoef[i,j] := 0.0; + end; + end; + + //Now, do the regression analysis for each model + for i := 1 to nocaused do + begin + NoVars := nocausing[i-1] + 1; + for j := 1 to nocausing[i-1] do + begin + col := causingseq[i-1,j-1]; + IndepIndex[j-1] := j; // independents + selected[j-1] := col; + Labels[j-1] := OS3MainFrm.DataGrid.Cells[col,0]; + end; + row := causedseq[i-1]; //sequence no. of caused variable + IndepIndex[NoVars-1] := row; // dependent + selected[NoVars-1] := row; + Labels[NoVars-1] := OS3MainFrm.DataGrid.Cells[row,0]; + + // get correlation matrix for this model + Correlations(NoVars, selected, WorkMat, means, variances, stddevs, errorcode, count); + if ModelChk.Checked then + begin + lReport.Add('Dependent Variable: %s', [OS3MainFrm.DataGrid.Cells[row,0]]); + lReport.Add(''); title := 'Correlation Matrix'; - MAT_PRINT(rmat,NoSelected,NoSelected,title,RowLabels,RowLabels,count); + MatPrint(WorkMat, NoVars, NoVars, title, Labels, Labels, count, lReport); + title := 'MEANS'; - DynVectorPrint(means,NoSelected,title,RowLabels,count); + DynVectorPrint(means, NoVars, title, Labels, count, lReport); + title := 'VARIANCES'; - DynVectorPrint(variances,NoSelected,title,RowLabels,count); + DynVectorPrint(variances, NoVars, title, Labels, count, lReport); + title := 'STANDARD DEVIATIONS'; - DynVectorPrint(stddevs,NoSelected,title,RowLabels,count); - OutputFrm.ShowModal; - OutputFrm.RichEdit.Clear; - end; + DynVectorPrint(stddevs, NoVars, title, Labels, count, lReport); - // initialize reconstruction matrix, weights matrix and path coefficients - for i := 0 to NoSelected-1 do - begin - for j := 0 to NoSelected-1 do - begin - e[i,j] := 0.0; - W[i,j] := 0.0; - PathCoef[i,j] := 0.0; - end; - end; + lReport.Add(DIVIDER); + lReport.Add(''); + end; - //Now, do the regression analysis for each model - for i := 1 to nocaused do - begin - NoVars := nocausing[i-1] + 1; - for j := 1 to nocausing[i-1] do - begin - col := causingseq[i-1,j-1]; - IndepIndex[j-1] := j; // independents - selected[j-1] := col; - Labels[j-1] := OS3MainFrm.DataGrid.Cells[col,0]; - end; - row := causedseq[i-1]; //sequence no. of caused variable - IndepIndex[NoVars-1] := row; // dependent - selected[NoVars-1] := row; - Labels[NoVars-1] := OS3MainFrm.DataGrid.Cells[row,0]; + // Get regression analysis for this model + ProbOut := 0.999; + NoIndepVars := NoVars - 1; + if StatsChk.Checked then + begin + lReport.Add('Dependent Variable: %s', [OS3MainFrm.DataGrid.Cells[row,0]]); + lReport.Add(''); + end; - // get correlation matrix for this model - Correlations(NoVars,selected,WorkMat,means,variances,stddevs, - errorcode,count); - if ModelChk.Checked then - begin - OutputFrm.RichEdit.Lines.Add(''); - outline := format('Dependent Variable = %s',[OS3MainFrm.DataGrid.Cells[row,0]]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - title := 'Correlation Matrix'; - MAT_PRINT(WorkMat,NoVars,NoVars,title,Labels,Labels,count); - title := 'MEANS'; - DynVectorPrint(means,NoVars,title,Labels,count); - title := 'VARIANCES'; - DynVectorPrint(variances,NoVars,title,Labels,count); - title := 'STANDARD DEVIATIONS'; - DynVectorPrint(stddevs,NoVars,title,Labels,count); - OutputFrm.ShowModal; - OutputFrm.RichEdit.Clear; - end; + prtopt := StatsChk.Checked; - // Get regression analysis for this model - ProbOut := 0.999; - NoIndepVars := NoVars - 1; - if StatsChk.Checked then - begin - OutputFrm.RichEdit.Lines.Add(''); - outline := format('Dependent Variable = %s',[OS3MainFrm.DataGrid.Cells[row,0]]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.RichEdit.Lines.Add(''); - end; - if StatsChk.Checked then prtopt := true else prtopt := false; - MReg2(count,NoVars,NoIndepVars,IndepIndex,WorkMat,IndMatrix, - Labels,R2,beta,means,variances,IER,StdErrEst,constant, - ProbOut,prtopt,false,false, OutputFrm.RichEdit.Lines); - if prtopt then - begin - OutputFrm.RichEdit.Lines.Add(''); - OutputFrm.ShowModal; - OutputFrm.RichEdit.Clear; - end; + MReg2(count, NoVars, NoIndepVars, IndepIndex, WorkMat, IndMatrix, + Labels, R2, beta, means, variances, IER, StdErrEst, constant, + ProbOut, prtopt, false, false, lReport); - for j := 1 to nocausing[i-1] do - begin - col := causingseq[i-1,j-1]; - PathCoef[row-1,col-1] := beta[j-1]; - end; - end; // next i (caused regressions) + if prtopt then + begin + lReport.Add(''); + lReport.Add(DIVIDER); + lReport.Add(''); + end; - //Now, reconstruct the correlation matrix from path coefficients - //First, obtain list of exogenous variables - noexogenous := 0; - for i := 1 to NoSelected do - begin - matched := false; - col := ColNoSelected[i-1]; - for j := 1 to nocaused do - if (causedseq[j-1] = col) then matched := true; - if ( not matched) then - begin - exogenous[noexogenous] := col; - noexogenous := noexogenous + 1; - end; - end; + for j := 1 to nocausing[i-1] do + begin + col := causingseq[i-1,j-1]; + PathCoef[row-1,col-1] := beta[j-1]; + end; + end; // next i (caused regressions) - // transform raw scores to z scores for exogenous variables - Correlations(NoSelected,ColNoSelected,rmat,means,variances,stddevs, - errorcode,count); - for i := 1 to noselected do genedz[i-1] := 0; // initialize - for k := 1 to noexogenous do - begin - col := exogenous[k-1]; - for j := 1 to noselected do - begin // find position of corresponding mean and std.dev. - if ColNoSelected[j-1] = col then row := j; - end; - for i := 1 to NoCases do - begin - zvals[i-1,col-1] := StrToFloat(OS3MainFrm.DataGrid.Cells[col,i]); - zvals[i-1,col-1] := (zvals[i-1,col-1] - means[row-1]) / stddevs[row-1]; - RowLabels[i-1] := format('Subject %d',[i]); - end; - genedz[col-1] := 1; // mark as generated - end; + //Now, reconstruct the correlation matrix from path coefficients + //First, obtain list of exogenous variables + noexogenous := 0; + for i := 1 to NoSelected do + begin + matched := false; + col := ColNoSelected[i-1]; + for j := 1 to nocaused do + if (causedseq[j-1] = col) then matched := true; + if not matched then + begin + exogenous[noexogenous] := col; + noexogenous := noexogenous + 1; + end; + end; + + // transform raw scores to z scores for exogenous variables + Correlations(NoSelected, ColNoSelected, rmat, means, variances, stddevs, errorcode, count); + + for i := 1 to noselected do + genedz[i-1] := 0; // initialize + for k := 1 to noexogenous do + begin + col := exogenous[k-1]; + // find position of corresponding mean and std.dev. + for j := 1 to noselected do + if ColNoSelected[j-1] = col then row := j; + for i := 1 to NoCases do + begin + zvals[i-1,col-1] := StrToFloat(OS3MainFrm.DataGrid.Cells[col,i]); + zvals[i-1,col-1] := (zvals[i-1,col-1] - means[row-1]) / stddevs[row-1]; + RowLabels[i-1] := format('Subject %d',[i]); + end; + genedz[col-1] := 1; // mark as generated + end; { - // print matrix of path z scores for exogenous variables - title := 'Data Array of Subject exogenous z Scores'; - MAT_PRINT(zvals,NoCases,NoSelected,title,RowLabels,ColLabels,NoCases); - OutputFrm.ShowModal; - OutputFrm.RichEdit.Clear; + // print matrix of path z scores for exogenous variables + title := 'Data Array of Subject exogenous z Scores'; + MAT_PRINT(zvals,NoCases,NoSelected,title,RowLabels,ColLabels,NoCases); + OutputFrm.ShowModal; + OutputFrm.RichEdit.Clear; } - for i := 1 to NoVariables do - begin - cellstring := OS3MainFrm.DataGrid.Cells[i,0]; - for j := 1 to NoSelected do + for i := 1 to NoVariables do + begin + cellstring := OS3MainFrm.DataGrid.Cells[i,0]; + for j := 1 to NoSelected do + begin + if cellstring = VarList.Items.Strings[j-1] then begin - if cellstring = VarList.Items.Strings[j-1] then - begin - RowLabels[i-1] := cellstring; - ColLabels[i-1] := cellstring; - end; + RowLabels[i-1] := cellstring; + ColLabels[i-1] := cellstring; end; + end; + end; + + //Build matrix of path coefficients + for i := 1 to nocaused do + begin + row := causedseq[i-1]; + for j := 1 to nocausing[i-1] do + begin + col := causingseq[i-1,j-1]; + W[row-1,col-1] := PathCoef[row-1,col-1]; + end; + end; + + //Print results + if StatsChk.Checked then + begin + title := 'Matrix of Path Coefficients in Rows'; + MatPrint(W, NoSelected, NoSelected, title, ColLabels, ColLabels, count, lReport); + lReport.Add(DIVIDER); + lReport.Add(''); end; - //Build matrix of path coefficients - for i := 1 to nocaused do - begin - row := causedseq[i-1]; - for j := 1 to nocausing[i-1] do - begin - col := causingseq[i-1,j-1]; - W[row-1,col-1] := PathCoef[row-1,col-1]; - end; - end; + //Build models vectors + k := 0; + for i := 1 to nocaused do + begin + for j := 1 to nocausing[i-1] do + begin + k := k + 1; + causal[0,k-1] := causedseq[i-1]; + causal[1,k-1] := causingseq[i-1,j-1]; + row := causedseq[i-1]; + col := causingseq[i-1,j-1]; + p[k-1] := PathCoef[row-1,col-1]; + end; + end; + NoModels := k; - //Print results - if StatsChk.Checked then - begin - title := 'Matrix of Path Coefficients in Rows'; - MAT_PRINT(W,NoSelected,NoSelected,title,ColLabels,ColLabels,count); - OutputFrm.ShowModal; - OutputFrm.RichEdit.Clear; - end; - - //Build models vectors - k := 0; - for i := 1 to nocaused do - begin - for j := 1 to nocausing[i-1] do - begin - k := k + 1; - causal[0,k-1] := causedseq[i-1]; - causal[1,k-1] := causingseq[i-1,j-1]; - row := causedseq[i-1]; - col := causingseq[i-1,j-1]; - p[k-1] := PathCoef[row-1,col-1]; - end; - end; - NoModels := k; - - //Sort on resultant then causing variables - for i := 1 to NoModels - 1 do - begin - for j := i + 1 to NoModels do - begin - if (causal[0,i-1] > causal[0,j-1]) then // swap - begin - t := causal[0,i-1]; - causal[0,i-1] := causal[0,j-1]; - causal[0,j-1] := t; + //Sort on resultant then causing variables + for i := 1 to NoModels - 1 do + begin + for j := i + 1 to NoModels do + begin + if (causal[0,i-1] > causal[0,j-1]) then // swap + begin + Exchange(causal[0, i-1], causal[0, j-1]); + { + t := causal[0,i-1]; + causal[0,i-1] := causal[0,j-1]; + causal[0,j-1] := t; + } + Exchange(causal[1, i-1], causal[1, j-1]); + { + t := causal[1,i-1]; + causal[1,i-1] := causal[1,j-1]; + causal[1,j-1] := t; + } + Exchange(p[i-1], p[j-1]); + { + Temp := p[i-1]; + p[i-1] := p[j-1]; + p[j-1] := Temp; + } + end; + end; + end; + for i := 1 to NoModels - 1 do + begin + for j := i + 1 to NoModels do + begin + if ((causal[0,i-1] = causal[0,j-1]) and (causal[1,i-1] > causal[1,j-1])) then + begin + Exchange(causal[0, i-1], causal[0, j-1]); + { + t := causal[0,i-1]; + causal[0,i-1] := causal[0,j-1]; + causal[0,j-1] := t; + } + Exchange(causal[1, i-1], causal[1, j-1]); + { t := causal[1,i-1]; causal[1,i-1] := causal[1,j-1]; causal[1,j-1] := t; + } + Exchange(p[i-1], p[j-1]); + { Temp := p[i-1]; p[i-1] := p[j-1]; p[j-1] := Temp; - end; - end; - end; - for i := 1 to NoModels - 1 do - begin - for j := i + 1 to NoModels do - begin - if ((causal[0,i-1] = causal[0,j-1]) and (causal[1,i-1] > causal[1,j-1])) then - begin - t := causal[0,i-1]; - causal[0,i-1] := causal[0,j-1]; - causal[0,j-1] := t; - t := causal[1,i-1]; - causal[1,i-1] := causal[1,j-1]; - causal[1,j-1] := t; - Temp := p[i-1]; - p[i-1] := p[j-1]; - p[j-1] := Temp; - end; - end; - end; + } + end; + end; + end; - OutputFrm.RichEdit.Lines.Add('SUMMARY OF CAUSAL MODELS'); - OutputFrm.RichEdit.Lines.Add('Var. Caused Causing Var. Path Coefficient'); + lReport.Add('SUMMARY OF CAUSAL MODELS'); + lReport.Add('Var. Caused Causing Var. Path Coefficient'); + lReport.Add('------------ ------------ ----------------'); - for i := 1 to NoModels do - begin - outline := format('%12s %12s %6.3f', - [OS3MainFrm.DataGrid.Cells[causal[0,i-1],0], - OS3MainFrm.DataGrid.Cells[causal[1,i-1],0], - p[i-1]]); - OutputFrm.RichEdit.Lines.Add(outline); - end; - OutputFrm.RichEdit.Lines.Add(''); - OutputFrm.ShowModal; - OutputFrm.RichEdit.Clear; + for i := 1 to NoModels do + lReport.Add('%12s %12s %12.3f', [ + OS3MainFrm.DataGrid.Cells[causal[0,i-1],0], + OS3MainFrm.DataGrid.Cells[causal[1,i-1],0], + p[i-1] + ]); + lReport.Add(''); + lReport.Add(DIVIDER); + lReport.Add(''); - //Get reproduced correlation matrix in e - done := false; - while not done do - begin - for i := 1 to nocaused do // check each caused for use of existing z values + //Get reproduced correlation matrix in e + done := false; + while not done do + begin + for i := 1 to nocaused do // check each caused for use of existing z values + begin + for j := 1 to nocausing[i-1] do begin - for j := 1 to nocausing[i-1] do - begin - count := 0; - for L := 1 to noselected do - begin - if genedz[L-1] = 1 then count := count + 1; - end; - end; - if count >= nocausing[i-1] then // calculate path z - begin - row := causedseq[i-1]; // generation z column & row of path coef. - for j := 1 to nocausing[i-1] do - begin // sum of Path coefficients times corresponding z's - col := causingseq[i-1,j-1]; // column of path coefficient - for k := 1 to NoCases do - begin - zscore := zvals[k-1,col-1]; // causing z score - zvals[k-1,row-1] := zvals[k-1,row-1] + zscore * PathCoef[row-1,col-1]; - end; - end; - genedz[row-1] := 1; // mark as generated - end; // if count equals no. of causing variables - count := 0; // check for completion of all z's - for j := 1 to noselected do - if genedz[j-1] = 1 then count := count + 1; - if count = noselected then done := true; - end; // next i caused variable - end; // while not done + count := 0; + for L := 1 to noselected do + if genedz[L-1] = 1 then count := count + 1; + end; + if count >= nocausing[i-1] then // calculate path z + begin + row := causedseq[i-1]; // generation z column & row of path coef. + for j := 1 to nocausing[i-1] do + begin // sum of Path coefficients times corresponding z's + col := causingseq[i-1,j-1]; // column of path coefficient + for k := 1 to NoCases do + begin + zscore := zvals[k-1,col-1]; // causing z score + zvals[k-1,row-1] := zvals[k-1,row-1] + zscore * PathCoef[row-1,col-1]; + end; + end; + genedz[row-1] := 1; // mark as generated + end; // if count equals no. of causing variables - // print matrix of path z scores - for i := 1 to NoCases do RowLabels[i-1] := format('Subject %d',[i]); - title := 'Data Array of Subject Path z Scores'; - MAT_PRINT(zvals,NoCases,NoSelected,title,RowLabels,ColLabels,NoCases); - OutputFrm.ShowModal; - OutputFrm.RichEdit.Clear; - - // now calculate the correlation among the generated z values - for i := 1 to noselected do - begin // initialize arrays + count := 0; // check for completion of all z's for j := 1 to noselected do - begin - e[i-1,j-1] := 0.0; - end; - means[i-1] := 0.0; - stddevs[i-1] := 0.0; - end; - for k := 1 to NoCases do - begin - for i := 1 to noselected do - begin - for j := 1 to noselected do - begin - e[i-1,j-1] := e[i-1,j-1] + zvals[k-1,i-1] * zvals[k-1,j-1]; - end; - means[i-1] := means[i-1] + zvals[k-1,i-1]; - stddevs[i-1] := stddevs[i-1] + (zvals[k-1,i-1] * zvals[k-1,i-1]); - end; - end; - for i := 1 to noselected do - begin - stddevs[i-1] := stddevs[i-1] - (means[i-1] * means[i-1] / NoCases); - stddevs[i-1] := stddevs[i-1] / (NoCases - 1); - stddevs[i-1] := sqrt(stddevs[i-1]); - for j := 1 to noselected do - begin // covariances - e[i-1,j-1] := e[i-1,j-1] - (means[i-1] * means[j-1] / NoCases); - e[i-1,j-1] := e[i-1,j-1] / (NoCases - 1); - end; - means[i-1] := means[i-1] / NoCases; - end; - for i := 1 to noselected do - begin - for j := 1 to noselected do - begin - e[i-1,j-1] := e[i-1,j-1] / (stddevs[i-1]*stddevs[j-1]); - end; - end; + if genedz[j-1] = 1 then count := count + 1; + if count = noselected then done := true; + end; // next i caused variable + end; // while not done - if (ReproChk.Checked) then - begin + // print matrix of path z scores + for i := 1 to NoCases do RowLabels[i-1] := Format('Subject %d',[i]); + title := 'Data Array of Subject Path z Scores'; + MatPrint(zvals, NoCases, NoSelected, title, RowLabels, ColLabels, NoCases, lReport); + lReport.Add(DIVIDER); + lReport.Add(''); + + // now calculate the correlation among the generated z values + for i := 1 to noselected do + begin // initialize arrays + for j := 1 to noselected do + e[i-1,j-1] := 0.0; + means[i-1] := 0.0; + stddevs[i-1] := 0.0; + end; + for k := 1 to NoCases do + begin + for i := 1 to noselected do + begin + for j := 1 to noselected do + e[i-1,j-1] := e[i-1,j-1] + zvals[k-1,i-1] * zvals[k-1,j-1]; + means[i-1] := means[i-1] + zvals[k-1,i-1]; + stddevs[i-1] := stddevs[i-1] + (zvals[k-1,i-1] * zvals[k-1,i-1]); + end; + end; + for i := 1 to noselected do + begin + stddevs[i-1] := stddevs[i-1] - (means[i-1] * means[i-1] / NoCases); + stddevs[i-1] := stddevs[i-1] / (NoCases - 1); + stddevs[i-1] := sqrt(stddevs[i-1]); + for j := 1 to noselected do + begin // covariances + e[i-1,j-1] := e[i-1,j-1] - (means[i-1] * means[j-1] / NoCases); + e[i-1,j-1] := e[i-1,j-1] / (NoCases - 1); + end; + means[i-1] := means[i-1] / NoCases; + end; + for i := 1 to noselected do + begin + for j := 1 to noselected do + e[i-1,j-1] := e[i-1,j-1] / (stddevs[i-1]*stddevs[j-1]); + end; + + if ReproChk.Checked then + begin title := 'Reproduced Correlation Matrix'; - MAT_PRINT(e,NoSelected,NoSelected,title,ColLabels,ColLabels,count); - end; + MatPrint(e, NoSelected, NoSelected, title, ColLabels, ColLabels, count, lReport); + end; - //Examine discrepencies - d2 := 0.0; - sum := 0.0; - for i := 1 to NoSelected do - begin - for j := 1 to NoSelected do - begin - absdiff := abs(rmat[i-1,j-1] - e[i-1,j-1]); - sum := sum + absdiff; - if (absdiff > d2) then d2 := absdiff; - end; - end; + //Examine discrepencies + d2 := 0.0; + sum := 0.0; + for i := 1 to NoSelected do + begin + for j := 1 to NoSelected do + begin + absdiff := abs(rmat[i-1,j-1] - e[i-1,j-1]); + sum := sum + absdiff; + if (absdiff > d2) then d2 := absdiff; + end; + end; - OutputFrm.RichEdit.Lines.Add('Average absolute difference between observed and reproduced'); - outline := format('coefficients := %5.3f',[sum / (NoSelected * NoSelected)]); - OutputFrm.RichEdit.Lines.Add(outline); - outline := format('Maximum difference found := %5.3f',[d2]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.ShowModal; + lReport.Add('Average absolute difference between observed and reproduced'); + lReport.Add('Coefficients: %5.3f', [sum / (NoSelected * NoSelected)]); + lReport.Add('Maximum difference found: %5.3f', [d2]); - // clean up heap (delete last allocated first) - genedz := nil; - zvals := nil; - selected := nil; - ColNoSelected := nil; - exogenous := nil; - IndepIndex := nil; - Labels := nil; - ColLabels := nil; - RowLabels := nil; - Causal := nil; - p := nil; - beta := nil; - stddevs := nil; - variances := nil; - means := nil; - W := nil; - e := nil; - InvMatrix := nil; - IndMatrix := nil; - PathCoef := nil; - WorkMat := nil; - rmat := nil; + DisplayReport(lReport); + + finally + lReport.Free; + genedz := nil; + zvals := nil; + selected := nil; + ColNoSelected := nil; + exogenous := nil; + IndepIndex := nil; + Labels := nil; + ColLabels := nil; + RowLabels := nil; + Causal := nil; + p := nil; + beta := nil; + stddevs := nil; + variances := nil; + means := nil; + W := nil; + e := nil; + InvMatrix := nil; + IndMatrix := nil; + PathCoef := nil; + WorkMat := nil; + rmat := nil; + end; end; +procedure TPathFrm.UpdateBtnStates; +var + varSelected: Boolean; +begin + varSelected := AnySelected(VarList); + InBtn.Enabled := AnySelected(ListBox1); + OutBtn.Enabled := varSelected; + CausedInBtn.Enabled := varSelected and (CausedEdit.Text = ''); + CausedOutBtn.Enabled := (CausedEdit.Text <> ''); + CausingInBtn.Enabled := varSelected; + CausingOutBtn.Enabled := AnySelected(CausingList); +end; initialization {$I pathunit.lrs} diff --git a/applications/lazstats/source/units/globals.pas b/applications/lazstats/source/units/globals.pas index 58c8c6fdf..278037c40 100644 --- a/applications/lazstats/source/units/globals.pas +++ b/applications/lazstats/source/units/globals.pas @@ -88,6 +88,8 @@ const clAqua, clLime, clFuchsia, clGray, clSilver, clOlive ); + DIVIDER = '==========================================================================='; + implementation