LazStats: Some more improvements in RaschUnit.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7898 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-11-22 22:29:04 +00:00
parent 29721742a0
commit 128c037e14
7 changed files with 176 additions and 102 deletions

View File

@ -565,8 +565,6 @@ end;
procedure TBNestedAForm.Reset; procedure TBNestedAForm.Reset;
var
i: integer;
begin begin
inherited; inherited;
@ -579,9 +577,7 @@ begin
BCodesEdit.Clear; BCodesEdit.Clear;
DepEdit.Clear; DepEdit.Clear;
VarList.Items.Clear; CollectVariableNames(OS3MainFrm.DataGrid, VarList.Items);
for i := 1 to NoVariables do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
end; end;

View File

@ -81,7 +81,7 @@ implementation
{$R *.lfm} {$R *.lfm}
uses uses
Utils, MathUnit; Utils, MathUnit, GridProcs;
{ TCanonicalForm } { TCanonicalForm }
@ -615,15 +615,11 @@ begin
end; end;
procedure TCanonicalForm.Reset; procedure TCanonicalForm.Reset;
var
i: integer;
begin begin
inherited; inherited;
LeftList.Clear; LeftList.Clear;
RightList.Clear; RightList.Clear;
VarList.Clear; CollectVariableNames(OS3MainFrm.DataGrid, VarList.Items);
for i := 1 to NoVariables do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
if FCreated then if FCreated then
begin begin

View File

@ -60,7 +60,7 @@ implementation
uses uses
TAChartUtils, TALegend, TAMultiSeries, TAChartUtils, TALegend, TAMultiSeries,
Math, Utils; Math, Utils, GridProcs;
const const
BOX_COLORS: Array[0..3] of TColor = (clBlue, clGreen, clFuchsia, clLime); BOX_COLORS: Array[0..3] of TColor = (clBlue, clGreen, clFuchsia, clLime);
@ -170,7 +170,7 @@ begin
maxGrp := -MaxInt; maxGrp := -MaxInt;
for i := 1 to NoCases do for i := 1 to NoCases do
begin begin
if not GoodRecord(i, Length(ColNoSelected), ColNoSelected) then continue; if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then continue;
G := round(StrToFloat(OS3MainFrm.DataGrid.Cells[GrpVar, i])); G := round(StrToFloat(OS3MainFrm.DataGrid.Cells[GrpVar, i]));
minGrp := Min(G, minGrp); minGrp := Min(G, minGrp);
maxGrp := Max(G, maxGrp); maxGrp := Max(G, maxGrp);
@ -191,7 +191,7 @@ begin
numValues := 0; numValues := 0;
for i := 1 to NoCases do for i := 1 to NoCases do
begin begin
if not GoodRecord(i, Length(ColNoSelected), ColNoSelected) then continue; if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then continue;
inc(numValues); inc(numValues);
X := StrToFloat(OS3MainFrm.DataGrid.Cells[MeasVar, i]); X := StrToFloat(OS3MainFrm.DataGrid.Cells[MeasVar, i]);
MaxScore := Max(MaxScore, X); MaxScore := Max(MaxScore, X);
@ -256,7 +256,7 @@ begin
cnt := 0; cnt := 0;
for i := 1 to NoCases do for i := 1 to NoCases do
begin // get scores for this group j begin // get scores for this group j
if not GoodRecord(i, Length(ColNoSelected), ColNoSelected) then continue; if not GoodRecord(OS3MainFrm.DataGrid, i, ColNoSelected) then continue;
G := round(StrToFloat(OS3MainFrm.DataGrid.Cells[GrpVar, i])); G := round(StrToFloat(OS3MainFrm.DataGrid.Cells[GrpVar, i]));
G := G - minGrp + 1; G := G - minGrp + 1;
if G = j+1 then // subject in this group if G = j+1 then // subject in this group
@ -392,7 +392,6 @@ begin
end; end;
end; end;
function TBoxPlotFrm.Percentile(nScoreGrps: integer; function TBoxPlotFrm.Percentile(nScoreGrps: integer;
APercentile: double; const Freq, CumFreq, Scores: DblDyneVec): double; APercentile: double; const Freq, CumFreq, Scores: DblDyneVec): double;
var var
@ -431,16 +430,13 @@ end;
procedure TBoxPlotFrm.Reset; procedure TBoxPlotFrm.Reset;
var
i: integer;
begin begin
inherited; inherited;
VarList.Clear; CollectVariableNames(OS3MainFrm.DataGrid, VarList.Items);
GroupEdit.Text := ''; GroupEdit.Text := '';
MeasEdit.Text := ''; MeasEdit.Text := '';
for i := 1 to NoVariables do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
UpdateBtnStates; UpdateBtnStates;
end; end;

View File

@ -140,6 +140,7 @@ inherited RaschForm: TRaschForm
Constraints.MinHeight = 220 Constraints.MinHeight = 220
ItemHeight = 0 ItemHeight = 0
MultiSelect = True MultiSelect = True
OnDblClick = VarListDblClick
OnSelectionChange = VarListSelectionChange OnSelectionChange = VarListSelectionChange
TabOrder = 0 TabOrder = 0
end end
@ -174,6 +175,7 @@ inherited RaschForm: TRaschForm
BorderSpacing.Top = 2 BorderSpacing.Top = 2
ItemHeight = 0 ItemHeight = 0
MultiSelect = True MultiSelect = True
OnDblClick = ItemListDblClick
OnSelectionChange = VarListSelectionChange OnSelectionChange = VarListSelectionChange
TabOrder = 3 TabOrder = 3
end end
@ -202,8 +204,9 @@ inherited RaschForm: TRaschForm
Left = 357 Left = 357
Height = 403 Height = 403
Width = 490 Width = 490
ActivePage = ItemFuncsPage inherited ReportPage: TTabSheet
TabIndex = 3 Caption = 'Results'
end
inherited ChartPage: TTabSheet inherited ChartPage: TTabSheet
Caption = 'Plot Item Difficulties' Caption = 'Plot Item Difficulties'
TabVisible = False TabVisible = False
@ -220,5 +223,9 @@ inherited RaschForm: TRaschForm
Caption = 'Plot Test Info' Caption = 'Plot Test Info'
TabVisible = False TabVisible = False
end end
object ProxPage: TTabSheet[5]
Caption = 'Prox'
TabVisible = False
end
end end
end end

View File

@ -11,7 +11,7 @@ interface
uses uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons,
ExtCtrls, ComCtrls, MainUnit, FunctionsLib, Globals, ExtCtrls, ComCtrls, MainUnit, FunctionsLib, Globals,
ChartFrameUnit, BasicStatsReportAndChartFormUnit; ReportFrameUnit, ChartFrameUnit, BasicStatsReportAndChartFormUnit;
type type
@ -24,6 +24,7 @@ type
ItemFuncsChk: TCheckBox; ItemFuncsChk: TCheckBox;
ScoresPage: TTabSheet; ScoresPage: TTabSheet;
ItemFuncsPage: TTabSheet; ItemFuncsPage: TTabSheet;
ProxPage: TTabSheet;
TestInfoPage: TTabSheet; TestInfoPage: TTabSheet;
TestInfoChk: TCheckBox; TestInfoChk: TCheckBox;
OptionsGroup: TGroupBox; OptionsGroup: TGroupBox;
@ -34,7 +35,9 @@ type
Label1: TLabel; Label1: TLabel;
VarList: TListBox; VarList: TListBox;
procedure InBtnClick(Sender: TObject); procedure InBtnClick(Sender: TObject);
procedure ItemListDblClick(Sender: TObject);
procedure OutBtnClick(Sender: TObject); procedure OutBtnClick(Sender: TObject);
procedure VarListDblClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean); procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean);
private private
@ -65,10 +68,10 @@ type
const P, p2: DblDyneVec; AReport: TStrings); const P, p2: DblDyneVec; AReport: TStrings);
procedure Prox(const P, p2: DblDyneVec; k, r, C1: integer; procedure Prox(const P, p2: DblDyneVec; k, r, C1: integer;
const L1: DblDyneVec; yexpand, xexpand: double; const g: DblDyneVec; const L1: DblDyneVec; yexpand, xexpand: double; const g: DblDyneVec;
T: integer; const rowtot, i5, s5: IntDyneVec; AReport: TStrings); T: integer; const rowtot, i5, s5: IntDyneVec);
function Reduce(k: integer; out r, T, C1: integer; function Reduce(k: integer; out r, T, C1: integer;
const i5, rowtot, s5: IntDyneVec; const f: IntDyneMat; const S: IntDyneVec; const i5, rowtot, s5: IntDyneVec; const f: IntDyneMat; const S: IntDyneVec;
AReport: TStrings): integer; AReport: TStrings): boolean;
procedure Slopes(const rptbis, rbis, slope: DblDyneVec; N: integer; procedure Slopes(const rptbis, rbis, slope: DblDyneVec; N: integer;
sumx, sumx2: double; const sumxy: DblDyneVec; r: integer; sumx, sumx2: double; const sumxy: DblDyneVec; r: integer;
const xsqr, mean: DblDyneVec); const xsqr, mean: DblDyneVec);
@ -81,10 +84,11 @@ type
procedure PlotItems(r: integer; const i5: IntDyneVec; const P: DblDyneVec); procedure PlotItems(r: integer; const i5: IntDyneVec; const P: DblDyneVec);
procedure PlotScrs(C1: integer; const s5: IntDyneVec; const p2: DblDyneVec); procedure PlotScrs(C1: integer; const s5: IntDyneVec; const p2: DblDyneVec);
procedure PlotTest(const TestInfo: DblDyneMat; ArraySize: integer; procedure PlotTest(const TestInfo: DblDyneMat; ArraySize: integer;
const Title: string{; Vdivisions, Hdivisions: integer}); const Title: string);
private private
FChartCombobox: TCombobox; FChartCombobox: TCombobox;
FProxReportFrame: TReportFrame;
FItemDiffsChartFrame: TChartFrame; FItemDiffsChartFrame: TChartFrame;
FScoresChartFrame: TChartFrame; FScoresChartFrame: TChartFrame;
FItemFuncsChartFrame: TChartFrame; FItemFuncsChartFrame: TChartFrame;
@ -106,6 +110,7 @@ type
var var
RaschForm: TRaschForm; RaschForm: TRaschForm;
implementation implementation
{$R *.lfm} {$R *.lfm}
@ -115,12 +120,16 @@ uses
TAChartUtils, TACustomSeries, TAChartUtils, TACustomSeries,
Utils, GridProcs; Utils, GridProcs;
{ TRaschForm } { TRaschForm }
constructor TRaschForm.Create(AOwner: TComponent); constructor TRaschForm.Create(AOwner: TComponent);
begin begin
inherited; inherited;
FReportFrame.ClearBorderSpacings;
InitToolbar(FReportFrame.ReportToolbar, tpTop);
FItemDiffsChartFrame := FChartFrame; // already created by ancestor FItemDiffsChartFrame := FChartFrame; // already created by ancestor
FScoresChartFrame := TChartFrame.Create(self); FScoresChartFrame := TChartFrame.Create(self);
@ -136,6 +145,13 @@ begin
FTestInfoChartFrame := TChartFrame.Create(self); FTestInfoChartFrame := TChartFrame.Create(self);
FTestInfoChartFrame.Parent := TestInfoPage; FTestInfoChartFrame.Parent := TestInfoPage;
FTestInfoChartFrame.Align := alClient; FTestInfoChartFrame.Align := alClient;
FProxReportFrame := TReportFrame.Create(self);
FProxReportFrame.Parent := ProxPage;
FProxReportFrame.Align := alClient;
ProxPage.PageIndex := 1;
PageControl.ActivePageIndex := 0;
end; end;
@ -267,7 +283,7 @@ begin
for i := 0 to NoSelected-1 do for i := 0 to NoSelected-1 do
colNoSelected[i] := GetVariableIndex(OS3MainFrm.DataGrid, ItemList.Items[i]); colNoSelected[i] := GetVariableIndex(OS3MainFrm.DataGrid, ItemList.Items[i]);
//begin ( main program ) // begin main program
finished := false; finished := false;
N := NoCases; N := NoCases;
k1 := NoSelected; k1 := NoSelected;
@ -275,8 +291,7 @@ begin
lReport := TStringList.Create; lReport := TStringList.Create;
try try
GetScores(NoSelected, ColNoSelected, NoCases, f, mean, xsqr, sumxy, S, X, sumx, sumx2, N, lReport); GetScores(NoSelected, ColNoSelected, NoCases, f, mean, xsqr, sumxy, S, X, sumx, sumx2, N, lReport);
error := Reduce(k1, r, T, C1, i5, rowtot, s5, f, S, lReport); if not Reduce(k1, r, T, C1, i5, rowtot, s5, f, S, lReport) then
if error = 1 then
exit; exit;
Frequencies(C1, r, f, rowtot, i5, s5, T, S, lReport); Frequencies(C1, r, f, rowtot, i5, s5, T, S, lReport);
@ -284,8 +299,9 @@ begin
v2 := 0.0; v2 := 0.0;
GetLogs(L, L1, L2, g, g2, f2, rowtot, k1, s5, S, T, r, C1, v1, v2, lReport); GetLogs(L, L1, L2, g, g2, f2, rowtot, k1, s5, S, T, r, C1, v1, v2, lReport);
Expand(v1, v2, xexpand, yexpand); Expand(v1, v2, xexpand, yexpand);
Prox(P, p2, k1, r, C1, L1, yexpand, xexpand, g, T, rowtot, i5, s5, lReport); Prox(P, p2, k1, r, C1, L1, yexpand, xexpand, g, T, rowtot, i5, s5);
// start iterations for the maximum-likelihood (SetLengthton-Rhapson procedure)
// Start iterations for the maximum likelihood (SetLengthton-Rhapson procedure)
// estimates // estimates
noloops := 0; noloops := 0;
@ -296,31 +312,31 @@ begin
finished := true finished := true
else else
Maxability(expdcnt, d2, e2, p1, p2, P, C1, r, D, s5, noloops, lReport); Maxability(expdcnt, d2, e2, p1, p2, P, C1, r, D, s5, noloops, lReport);
noloops := noloops + 1; noloops := noloops + 1;
if (noloops > 25) then if (noloops > 25) then
begin begin
MessageDlg('Maximum Likelihood failed to converge after 25 iterations', mtInformation, [mbOK], 0); ErrorMsg('Maximum Likelihood failed to converge after 25 iterations');
finished := true; finished := true;
end; end;
end; end;
MaxOut(r, C1, i5, s5, P, p2, lReport); MaxOut(r, C1, i5, s5, P, p2, lReport);
TestFit(r, C1, f, S, P, p2, T, lReport); TestFit(r, C1, f, S, P, p2, T, lReport);
Slopes(rptbis, rbis, slope, N, sumx, sumx2, sumxy, r, xsqr, mean); Slopes(rptbis, rbis, slope, N, sumx, sumx2, sumxy, r, xsqr, mean);
Analyze(itemfail, grpfail, f, T, grppass, itempass, r, C1, min, max, p2); Analyze(itemfail, grpfail, f, T, grppass, itempass, r, C1, min, max, p2);
if PlotItemDiffChk.Checked then PlotItems(r, i5, P); PlotItems(r, i5, P);
if PlotScrsChk.Checked then PlotScrs(C1, s5, p2); PlotScrs(C1, s5, p2);
PlotInfo(r, info, A, slope, P); PlotInfo(r, info, A, slope, P);
ChartPage.TabVisible := PlotItemDiffChk.Checked;
ScoresPage.TabVisible := PlotScrsChk.Checked;
ItemFuncsPage.TabVisible := ItemFuncsChk.Checked;
TestInfopage.TabVisible := TestInfoChk.Checked;
FinishIt(r, i5, rptbis, rbis, slope, mean, itemfail, P, lReport); FinishIt(r, i5, rptbis, rbis, slope, mean, itemfail, P, lReport);
FReportFrame.DisplayReport(lReport); FReportFrame.DisplayReport(lReport);
ProxPage.TabVisible := ProxChk.Checked;
ChartPage.TabVisible := PlotItemDiffChk.Checked;
ScoresPage.TabVisible := PlotScrsChk.Checked;
ItemFuncsPage.TabVisible := ItemFuncsChk.Checked;
TestInfoPage.TabVisible := TestInfoChk.Checked;
finally finally
lReport.Free; lReport.Free;
end; end;
@ -340,6 +356,8 @@ procedure TRaschForm.FinishIt(r: integer; const i5: IntDyneVec;
var var
i: integer; i: integer;
begin begin
AReport.Add('');
AReport.Add(DIVIDER_SMALL_AUTO);
AReport.Add(''); AReport.Add('');
AReport.Add('Item Data Summary'); AReport.Add('Item Data Summary');
AReport.Add(''); AReport.Add('');
@ -547,6 +565,20 @@ begin
end; end;
procedure TRaschForm.ItemListDblClick(Sender: TObject);
var
index: Integer;
begin
index := ItemList.ItemIndex;
if index > -1 then
begin
VarList.Items.Add(ItemList.Items[index]);
ItemList.Items.Delete(index);
UpdateBtnStates;
end;
end;
procedure TRaschForm.Maxability(const expdcnt, d2, e2: DblDyneVec; procedure TRaschForm.Maxability(const expdcnt, d2, e2: DblDyneVec;
const p1: DblDyneMat; const p2, P: DblDyneVec; C1, r: integer; const p1: DblDyneMat; const p2, P: DblDyneVec; C1, r: integer;
const D: DblDyneMat; const s5: IntDyneVec; noloops: integer; AReport: TStrings); const D: DblDyneMat; const s5: IntDyneVec; noloops: integer; AReport: TStrings);
@ -554,8 +586,9 @@ var
i, j: integer; i, j: integer;
d9: double; d9: double;
begin begin
AReport.Add('Maximum Likelihood Iteration Number %d', [noLoops]);
d9 := 0.0; d9 := 0.0;
AReport.Add('Maximum Likelihood Iteration Number %d', [noloops]);
for j := 0 to C1-1 do for j := 0 to C1-1 do
begin begin
expdcnt[j] := 0.0; expdcnt[j] := 0.0;
@ -568,7 +601,7 @@ begin
for i := 0 to r-1 do for i := 0 to r-1 do
begin begin
expdcnt[j] := expdcnt[j] + p1[i,j]; expdcnt[j] := expdcnt[j] + p1[i,j];
// expected number in score group // Expected number in score group
D[i,j] := exp(p2[j] - P[i]) / (sqrt(1.0 + exp(p2[j] - P[i]))); D[i,j] := exp(p2[j] - P[i]) / (sqrt(1.0 + exp(p2[j] - P[i])));
d2[j] := d2[j] + D[i,j]; // rate of change value d2[j] := d2[j] + D[i,j]; // rate of change value
end; end;
@ -624,7 +657,7 @@ begin
end; end;
e1[i] := e1[i] / d1[i]; e1[i] := e1[i] / d1[i];
// adjustment for item difficulty estimates // Adjustment for item difficulty estimates
if (abs(e1[i]) > d9) then d9 := abs(e1[i]); if (abs(e1[i]) > d9) then d9 := abs(e1[i]);
P[i] := P[i] + e1[i]; P[i] := P[i] + e1[i];
end; end;
@ -649,6 +682,8 @@ procedure TRaschForm.MAXOUT(r, C1: integer; const i5, s5: IntDyneVec;
var var
i, j: integer; i, j: integer;
begin begin
AReport.Add('');
AReport.Add(DIVIDER_SMALL_AUTO);
AReport.Add(''); AReport.Add('');
AReport.Add('Maximum Likelihood Estimates'); AReport.Add('Maximum Likelihood Estimates');
AReport.Add(''); AReport.Add('');
@ -777,6 +812,9 @@ var
i: integer; i: integer;
ser: TChartSeries; ser: TChartSeries;
begin begin
if not PlotItemDiffChk.Checked then
exit;
FItemDiffsChartFrame.Clear; FItemDiffsChartFrame.Clear;
FItemDiffsChartFrame.SetTitle('LOG DIFFICULTIES FOR ITEMS'); FItemDiffsChartFrame.SetTitle('LOG DIFFICULTIES FOR ITEMS');
FItemDiffsChartFrame.SetXTitle('Item'); FItemDiffsChartFrame.SetXTitle('Item');
@ -799,6 +837,9 @@ var
i: integer; i: integer;
ser: TChartSeries; ser: TChartSeries;
begin begin
if not PlotScrsChk.Checked then
exit;
FScoresChartFrame.Clear; FScoresChartFrame.Clear;
FScoresChartFrame.SetTitle('LOG ABILITIES FOR SCORE GROUPS'); FScoresChartFrame.SetTitle('LOG ABILITIES FOR SCORE GROUPS');
FScoresChartFrame.SetXTitle('Score'); FScoresChartFrame.SetXTitle('Score');
@ -814,7 +855,7 @@ end;
procedure TRaschForm.PlotTest(const TestInfo: DblDyneMat; procedure TRaschForm.PlotTest(const TestInfo: DblDyneMat;
ArraySize: integer; const Title: string{; Vdivisions, Hdivisions: integer}); ArraySize: integer; const Title: string);
var var
i: integer; i: integer;
ser: TChartSeries; ser: TChartSeries;
@ -834,10 +875,11 @@ end;
procedure TRaschForm.Prox(const P, p2: DblDyneVec; k, r, C1 : integer; procedure TRaschForm.Prox(const P, p2: DblDyneVec; k, r, C1 : integer;
const L1: DblDyneVec; yexpand, xexpand: double; const g: DblDyneVec; const L1: DblDyneVec; yexpand, xexpand: double; const g: DblDyneVec;
T: integer; const rowtot, i5, s5: IntDyneVec; AReport: TStrings); T: integer; const rowtot, i5, s5: IntDyneVec);
var var
tx, rowtx, errorterm, stdError: double; tx, rowtx, errorterm, stdError: double;
i, j: integer; i, j: integer;
lReport: TStrings;
begin begin
for i := 0 to r-1 do P[i] := L1[i] * yexpand; for i := 0 to r-1 do P[i] := L1[i] * yexpand;
for j := 0 to C1-1 do p2[j] := g[j] * xexpand; for j := 0 to C1-1 do p2[j] := g[j] * xexpand;
@ -845,56 +887,61 @@ begin
if not ProxChk.Checked then if not ProxChk.Checked then
exit; exit;
AReport.Add(''); lReport := TStringList.Create;
AReport.Add('Prox values and Standard Errors' ); try
AReport.Add(''); lReport.Add('Prox values and Standard Errors' );
AReport.Add('Item Scale Value Standard Error'); lReport.Add('');
AReport.Add('---- ----------- --------------'); lReport.Add('Item Scale Value Standard Error');
//xxx xxxxxxx xxxxxxx lReport.Add('---- ----------- --------------');
//xxx xxxxxxx xxxxxxx
tx := T; tx := T;
for i := 0 to r-1 do for i := 0 to r-1 do
begin begin
rowtx := rowtot[i]; rowtx := rowtot[i];
errorterm := tx / ((tx - rowtx) * rowtx); errorterm := tx / ((tx - rowtx) * rowtx);
stdError := yexpand * sqrt(errorterm); stdError := yexpand * sqrt(errorterm);
if ProxChk.checked then lReport.Add('%3d %7.3f %7.3f', [i5[i], P[i], stdError]);
AReport.Add('%3d %7.3f %7.3f', [i5[i], P[i], stdError]); end;
lReport.Add('Y expansion factor: %8.4f', [yexpand]);
lReport.Add('');
lReport.Add('Score Scale Value Standard Error');
lReport.Add('----- ----------- --------------');
// xxx xxxxxxx xxxxxxx
for j := 0 to C1-1 do
begin
stdError := xexpand * sqrt(k / (s5[j] * (k - s5[j])));
lReport.Add(' %3d %7.3f %7.3f', [s5[j], p2[j], stdError]);
end;
lReport.Add('X expansion factor: %8.4f', [xexpand]);
FProxReportFrame.DisplayReport(lReport);
finally
lReport.Free;
end; end;
AReport.Add('Y expansion factor: %8.4f', [yexpand]);
AReport.Add('');
AReport.Add('Score Scale Value Standard Error');
AReport.Add('----- ----------- --------------');
// xxx xxxxxxx xxxxxxx
for j := 0 to C1-1 do
begin
stdError := xexpand * sqrt(k / (s5[j] * (k - s5[j])));
AReport.Add(' %3d %7.3f %7.3f', [s5[j], p2[j], stdError]);
end;
AReport.Add('X expansion factor: %8.4f', [xexpand]);
AReport.Add('');
end; end;
function TRaschForm.Reduce(k: integer; out r, T, C1: Integer; function TRaschForm.Reduce(k: integer; out r, T, C1: Integer;
const i5, RowTot, s5: IntDyneVec; const f: IntDyneMat; const S: IntDyneVec; const i5, RowTot, s5: IntDyneVec; const f: IntDyneMat; const S: IntDyneVec;
AReport: TStrings): integer; AReport: TStrings): boolean;
var var
done: boolean; done: boolean;
check, i, j, column, row: integer; check, i, j, column, row: integer;
begin begin
// NOW REDUCE THE MATRIX BY ELIMINATING 0 OR 1 ROWS AND COLUMNS // Reduce the matrix by eliminating 0 or 1 rows and columns
AReport.Add(''); AReport.Add('');
//Store item numbers in i5 array and initialize row totals // Store item numbers in i5 array and initialize row totals
for i := 0 to k-1 do for i := 0 to k-1 do
begin begin
i5[i] := i+1; i5[i] := i+1;
rowtot[i] := 0; rowtot[i] := 0;
end; end;
//Store group numbers in s5 array // Store group numbers in s5 array
r := k; r := k;
T := 0; T := 0;
C1 := k - 1; // No. of score groups (all correct group eliminated) C1 := k - 1; // No. of score groups (all correct group eliminated)
@ -904,11 +951,11 @@ begin
T := T + S[j]; T := T + S[j];
end; end;
//Get row totals of the failures matrix (item totals) // Get row totals of the failures matrix (item totals)
for i := 0 to r-1 do for i := 0 to r-1 do
for j := 0 to C1-1 do rowtot[i] := rowtot[i] + f[i,j]; for j := 0 to C1-1 do rowtot[i] := rowtot[i] + f[i,j];
// now check for item elimination // Check for item elimination
done := false; done := false;
while not done do while not done do
begin begin
@ -919,7 +966,8 @@ begin
AReport.Add('Row %3d for item %3d eliminated.', [i, i5[i-1]]); AReport.Add('Row %3d for item %3d eliminated.', [i, i5[i-1]]);
if (i < r) then if (i < r) then
begin begin
for j := i to r-1 do //move rows up to replace row i // Move rows up to replace row i
for j := i to r-1 do
begin begin
for column := 1 to C1 do for column := 1 to C1 do
f[j-1, column-1] := f[j, column-1]; f[j-1, column-1] := f[j, column-1];
@ -938,7 +986,7 @@ begin
done := true; done := true;
end; end;
// check for group elimination // Check for group elimination
done := false; done := false;
j := 1; j := 1;
while (not done) do while (not done) do
@ -963,10 +1011,10 @@ begin
if C1 = 0 then if C1 = 0 then
begin begin
MessageDlg('Too many cases or variables eliminated', mtError, [mbOK], 0); ErrorMsg('Too many cases or variables eliminated');
FReportFrame.DisplayReport(AReport); FReportFrame.DisplayReport(AReport);
AReport.clear; AReport.Clear;
Result := 1; Result := false;
exit; exit;
end; end;
@ -980,10 +1028,10 @@ begin
C1 := C1 - 1; C1 := C1 - 1;
if C1 = 0 then if C1 = 0 then
begin begin
MessageDlg('Too many cases or variables eliminated', mtError, [mbOK], 0); ErrorMsg('Too many cases or variables eliminated');
FReportFrame.DisplayReport(AReport); FReportFrame.DisplayReport(AReport);
AReport.Clear; AReport.Clear;
Result := 1; Result := false;
exit; exit;
end; end;
end; end;
@ -993,24 +1041,27 @@ begin
AReport.Add('Total number of score groups: %4d', [C1]); AReport.Add('Total number of score groups: %4d', [C1]);
AReport.Add(''); AReport.Add('');
Result := 0; Result := true;
end; // end of reduce end;
procedure TRaschForm.Reset; procedure TRaschForm.Reset;
var
i: integer;
begin begin
inherited; inherited;
if FProxReportFrame <> nil then FProxReportFrame.Clear;
if FItemDiffsChartFrame <> nil then FItemDiffsChartFrame.Clear; if FItemDiffsChartFrame <> nil then FItemDiffsChartFrame.Clear;
if FScoresChartFrame <> nil then FScoresChartFrame.Clear; if FScoresChartFrame <> nil then FScoresChartFrame.Clear;
if FItemFuncsChartFrame <> nil then FItemFuncsChartFrame.Clear; if FItemFuncsChartFrame <> nil then FItemFuncsChartFrame.Clear;
if FTestInfoChartFrame <> nil then FTestInfoChartFrame.Clear; if FTestInfoChartFrame <> nil then FTestInfoChartFrame.Clear;
VarList.Clear; ProxPage.TabVisible := false;
for i := 1 to NoVariables do ChartPage.TabVisible := false;
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); ScoresPage.TabVisible := false;
ItemFuncsPage.TabVisible := false;
TestInfoPage.TabVisible := false;
CollectVariableNames(OS3MainFrm.DataGrid, VarList.Items);
ItemList.Clear; ItemList.Clear;
ProxChk.Checked := false; ProxChk.Checked := false;
@ -1081,6 +1132,8 @@ var
i, j: integer; i, j: integer;
outline: string; outline: string;
begin begin
AReport.Add('');
AReport.Add(DIVIDER_SMALL_AUTO);
AReport.Add(''); AReport.Add('');
AReport.Add('Goodness of Fit Test for Each Item'); AReport.Add('Goodness of Fit Test for Each Item');
AReport.Add(''); AReport.Add('');
@ -1107,6 +1160,7 @@ procedure TRaschForm.UpdateBtnStates;
begin begin
inherited; inherited;
if FProxReportFrame <> nil then FProxReportFrame.UpdateBtnStates;
if FItemDiffsChartFrame <> nil then FItemDiffsChartFrame.UpdateBtnStates; if FItemDiffsChartFrame <> nil then FItemDiffsChartFrame.UpdateBtnStates;
if FScoresChartFrame <> nil then FScoresChartFrame.UpdateBtnStates; if FScoresChartFrame <> nil then FScoresChartFrame.UpdateBtnStates;
if FItemFuncsChartFrame <> nil then FItemFuncsChartFrame.UpdateBtnStates; if FItemFuncsChartFrame <> nil then FItemFuncsChartFrame.UpdateBtnStates;
@ -1132,6 +1186,20 @@ begin
end; end;
procedure TRaschForm.VarListDblClick(Sender: TObject);
var
index: Integer;
begin
index := VarList.ItemIndex;
if index > -1 then
begin
ItemList.Items.Add(VarList.Items[index]);
VarList.Items.Delete(index);
UpdateBtnStates;
end;
end;
procedure TRaschForm.VarListSelectionChange(Sender: TObject; User: boolean); procedure TRaschForm.VarListSelectionChange(Sender: TObject; User: boolean);
begin begin
UpdateBtnStates; UpdateBtnStates;

View File

@ -789,20 +789,19 @@ end;
procedure TKMeansForm.Reset; procedure TKMeansForm.Reset;
var
i: integer;
begin begin
inherited; inherited;
CollectVariableNames(OS3MainFrm.DataGrid, VarList.Items);
SelList.Clear; SelList.Clear;
VarList.Clear;
for i := 1 to NoVariables do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
ReplaceChk.Checked := false; ReplaceChk.Checked := false;
StandardizeChk.Checked := true; StandardizeChk.Checked := true;
DescriptiveChk.Checked := false; DescriptiveChk.Checked := false;
NoClustersEdit.Clear; NoClustersEdit.Clear;
ItersEdit.Text := '100'; ItersEdit.Text := '100';
UpdateBtnStates; UpdateBtnStates;
end; end;

View File

@ -8,6 +8,8 @@ uses
Classes, SysUtils, Grids, Classes, SysUtils, Grids,
Globals, DictionaryUnit; Globals, DictionaryUnit;
procedure CollectVariableNames(AGrid: TStringGrid; AList: TStrings);
function CollectVecValues(AGrid: TStringGrid; AColIndex: Integer; function CollectVecValues(AGrid: TStringGrid; AColIndex: Integer;
AColCheck: IntDyneVec = nil): DblDyneVec; AColCheck: IntDyneVec = nil): DblDyneVec;
@ -42,6 +44,16 @@ implementation
uses uses
Math; Math;
procedure CollectVariableNames(AGrid: TStringGrid; AList: TStrings);
var
i: Integer;
begin
AList.Clear;
for i := 1 to AGrid.ColCount-1 do
AList.Add(AGrid.Cells[i, 0]);
end;
{ Extracts the values in the given column from the grid and returns them as an { Extracts the values in the given column from the grid and returns them as an
array. array.
Cells which are filtered or empty are not considered. This check is extended Cells which are filtered or empty are not considered. This check is extended