LazStats: Remove Cancel btn from FactorUnit, improved usability of arrow btns, write report to StringList, not to OutputFrm directly. Add pdf to help file. Add Exchange() procedure to Utils.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7364 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-04-09 09:05:26 +00:00
parent c222b83196
commit e67df71726
8 changed files with 1433 additions and 1345 deletions

View File

@ -1,7 +1,7 @@
object CannonFrm: TCannonFrm object CannonFrm: TCannonFrm
Left = 261 Left = 350
Height = 379 Height = 379
Top = 157 Top = 137
Width = 401 Width = 401
AutoSize = True AutoSize = True
Caption = 'Canonical Correlation Analysis' Caption = 'Canonical Correlation Analysis'

View File

@ -13,83 +13,65 @@ object FactorFrm: TFactorFrm
Position = poMainFormCenter Position = poMainFormCenter
LCLVersion = '2.1.0.0' LCLVersion = '2.1.0.0'
object ResetBtn: TButton object ResetBtn: TButton
AnchorSideRight.Control = CancelBtn AnchorSideRight.Control = ComputeBtn
AnchorSideBottom.Control = Owner AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 326 Left = 418
Height = 25 Height = 25
Top = 489 Top = 489
Width = 54 Width = 54
Anchors = [akRight, akBottom] Anchors = [akRight, akBottom]
AutoSize = True AutoSize = True
BorderSpacing.Left = 12 BorderSpacing.Left = 8
BorderSpacing.Top = 8 BorderSpacing.Top = 8
BorderSpacing.Right = 12 BorderSpacing.Right = 8
BorderSpacing.Bottom = 8 BorderSpacing.Bottom = 8
Caption = 'Reset' Caption = 'Reset'
OnClick = ResetBtnClick OnClick = ResetBtnClick
TabOrder = 2 TabOrder = 2
end end
object CancelBtn: TButton
AnchorSideRight.Control = ComputeBtn
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 392
Height = 25
Top = 489
Width = 62
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Left = 12
BorderSpacing.Top = 8
BorderSpacing.Right = 12
BorderSpacing.Bottom = 8
Caption = 'Cancel'
ModalResult = 2
TabOrder = 3
end
object ComputeBtn: TButton object ComputeBtn: TButton
AnchorSideRight.Control = ReturnBtn AnchorSideRight.Control = CloseBtn
AnchorSideBottom.Control = Owner AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 466 Left = 480
Height = 25 Height = 25
Top = 489 Top = 489
Width = 76 Width = 76
Anchors = [akRight, akBottom] Anchors = [akRight, akBottom]
AutoSize = True AutoSize = True
BorderSpacing.Left = 12 BorderSpacing.Left = 8
BorderSpacing.Top = 8 BorderSpacing.Top = 8
BorderSpacing.Right = 12 BorderSpacing.Right = 8
BorderSpacing.Bottom = 8 BorderSpacing.Bottom = 8
Caption = 'Compute' Caption = 'Compute'
OnClick = ComputeBtnClick OnClick = ComputeBtnClick
TabOrder = 4 TabOrder = 3
end end
object ReturnBtn: TButton object CloseBtn: TButton
AnchorSideRight.Control = Owner AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 554 Left = 564
Height = 25 Height = 25
Top = 489 Top = 489
Width = 61 Width = 55
Anchors = [akRight, akBottom] Anchors = [akRight, akBottom]
AutoSize = True AutoSize = True
BorderSpacing.Left = 12 BorderSpacing.Left = 8
BorderSpacing.Top = 8 BorderSpacing.Top = 8
BorderSpacing.Right = 12 BorderSpacing.Right = 8
BorderSpacing.Bottom = 8 BorderSpacing.Bottom = 8
Caption = 'Return' Caption = 'Close'
ModalResult = 1 ModalResult = 11
TabOrder = 5 TabOrder = 4
end end
object Bevel2: TBevel object Bevel2: TBevel
AnchorSideLeft.Control = Owner AnchorSideLeft.Control = Owner
AnchorSideRight.Control = Owner AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = ReturnBtn AnchorSideBottom.Control = CloseBtn
Left = 0 Left = 0
Height = 8 Height = 8
Top = 473 Top = 473
@ -293,7 +275,7 @@ object FactorFrm: TFactorFrm
BorderSpacing.Top = 4 BorderSpacing.Top = 4
BorderSpacing.Right = 8 BorderSpacing.Right = 8
TabOrder = 2 TabOrder = 2
Text = 'Edit1' Text = 'MaxItersEdit'
end end
object MaxFactorsEdit: TEdit object MaxFactorsEdit: TEdit
AnchorSideLeft.Control = Label5 AnchorSideLeft.Control = Label5
@ -310,7 +292,7 @@ object FactorFrm: TFactorFrm
BorderSpacing.Top = 4 BorderSpacing.Top = 4
BorderSpacing.Right = 8 BorderSpacing.Right = 8
TabOrder = 3 TabOrder = 3
Text = 'Edit1' Text = 'MaxFactorsEdit'
end end
end end
object Panel3: TPanel object Panel3: TPanel
@ -383,6 +365,7 @@ object FactorFrm: TFactorFrm
BorderSpacing.Right = 8 BorderSpacing.Right = 8
ItemHeight = 0 ItemHeight = 0
MultiSelect = True MultiSelect = True
OnSelectionChange = VarListSelectionChange
TabOrder = 0 TabOrder = 0
end end
object InBtn: TBitBtn object InBtn: TBitBtn
@ -417,6 +400,8 @@ object FactorFrm: TFactorFrm
BorderSpacing.Left = 8 BorderSpacing.Left = 8
BorderSpacing.Top = 2 BorderSpacing.Top = 2
ItemHeight = 0 ItemHeight = 0
MultiSelect = True
OnSelectionChange = VarListSelectionChange
TabOrder = 3 TabOrder = 3
end end
object OutBtn: TBitBtn object OutBtn: TBitBtn

View File

@ -9,7 +9,7 @@ uses
StdCtrls, ExtCtrls, Clipbrd, StdCtrls, ExtCtrls, Clipbrd,
Globals, OptionsUnit, DictionaryUnit, OutputUnit; Globals, OptionsUnit, DictionaryUnit, OutputUnit;
Function GoodRecord(Row, NoVars : integer; VAR GridPos : IntDyneVec): boolean; Function GoodRecord(Row, NoVars: integer; const GridPos: IntDyneVec): boolean;
procedure FormatCell(Col, Row : integer); procedure FormatCell(Col, Row : integer);
procedure FormatGrid; procedure FormatGrid;
function IsNumeric(s : string) : boolean; function IsNumeric(s : string) : boolean;
@ -31,9 +31,9 @@ procedure OpenTabFile;
procedure SaveTabFile; procedure SaveTabFile;
function ValidValue(row, col : integer) : boolean; function ValidValue(row, col : integer) : boolean;
function IsFiltered(GridRow : integer) : boolean; function IsFiltered(GridRow : integer) : boolean;
procedure MatRead(var a: DblDyneMat; out NoRows, NoCols: integer; procedure MatRead(const a: DblDyneMat; out NoRows, NoCols: integer;
var Means, StdDevs: DblDyneVec; out NCases: integer; const Means, StdDevs: DblDyneVec; out NCases: integer;
var RowLabels, ColLabels: StrDyneVec; const filename: string); const RowLabels, ColLabels: StrDyneVec; const filename: string);
procedure MATSAVE(VAR a : DblDyneMat; procedure MATSAVE(VAR a : DblDyneMat;
norows : integer; norows : integer;
nocols : integer; nocols : integer;
@ -62,19 +62,18 @@ implementation
uses MainUnit; uses MainUnit;
Function GoodRecord(Row, NoVars : integer; VAR GridPos : IntDyneVec): boolean; Function GoodRecord(Row, NoVars: integer; const GridPos: IntDyneVec): boolean;
var var
i, j : integer; i, j: integer;
isgood : boolean; isgood: boolean;
begin begin
isgood := true; Result := true;
for i := 1 to NoVars do for i := 1 to NoVars do
begin begin
j := GridPos[i-1]; j := GridPos[i-1];
if NOT ValidValue(Row,j) then isgood := false; if not ValidValue(Row,j) then
end; Result := false;
Result := isgood; end;
end; end;
//------------------------------------------------------------------- //-------------------------------------------------------------------
@ -826,11 +825,11 @@ begin
end; end;
//------------------------------------------------------------------- //-------------------------------------------------------------------
procedure MATREAD(var a: DblDyneMat; procedure MATREAD(const a: DblDyneMat;
out NoRows, NoCols: integer; out NoRows, NoCols: integer;
var means, stddevs: DblDyneVec; const means, stddevs: DblDyneVec;
out NCases: integer; out NCases: integer;
var RowLabels, ColLabels: StrDyneVec; const RowLabels, ColLabels: StrDyneVec;
const filename: string); const filename: string);
var i, j : integer; var i, j : integer;
mat_file : TextFile; mat_file : TextFile;

View File

@ -34,8 +34,8 @@ procedure Correlations(NoSelected : integer;
VAR errorcode : boolean; VAR errorcode : boolean;
VAR Ngood : integer); VAR Ngood : integer);
procedure MatAxB(var A, B, C: DblDyneMat; BRows, BCols, CRows, CCols: Integer; procedure MatAxB(const A, B, C: DblDyneMat; BRows, BCols, CRows, CCols: Integer;
var ErrorCode: boolean); out ErrorCode: boolean);
procedure MatTrn(var A, B: DblDyneMat; BRows, BCols: Integer); procedure MatTrn(var A, B: DblDyneMat; BRows, BCols: Integer);
@ -175,21 +175,17 @@ function SCPF(VAR x,y : DblDyneMat; kx,ky,n,nd : integer) : double;
procedure Mat_Print(var xmat: DblDyneMat; Rows,Cols: Integer; var Title: String; procedure Mat_Print(var xmat: DblDyneMat; Rows,Cols: Integer; var Title: String;
var RowLabels, ColLabels: StrDyneVec; NCases: Integer); var RowLabels, ColLabels: StrDyneVec; NCases: Integer);
procedure MatPrint(var xmat: DblDyneMat; Rows,Cols: Integer; var Title: String; procedure MatPrint(const xmat: DblDyneMat; Rows,Cols: Integer; const Title: String;
var RowLabels, ColLabels: StrDyneVec; NCases: Integer; AReport: TStrings); const RowLabels, ColLabels: StrDyneVec; NCases: Integer; AReport: TStrings);
procedure DynVectorPrint(var AVector: DblDyneVec; NoVars: integer; procedure DynVectorPrint(var AVector: DblDyneVec; NoVars: integer;
Title: string; var Labels: StrDyneVec; NCases: integer); overload; Title: string; var Labels: StrDyneVec; NCases: integer); overload;
procedure DynVectorPrint(var AVector: DblDyneVec; NoVars: integer; procedure DynVectorPrint(var AVector: DblDyneVec; NoVars: integer;
Title: string; var Labels: StrDyneVec; NCases: integer; AReport: TStrings); overload; Title: string; var Labels: StrDyneVec; NCases: integer; AReport: TStrings); overload;
procedure scatplot(var x : DblDyneVec; procedure scatplot(const x, y: DblDyneVec; NoCases: integer;
var y : DblDyneVec; const TitleStr, x_axis, y_axis: string; x_min, x_max, y_min, y_max: double;
nocases : integer; const VarLabels: StrDyneVec; AReport: TStrings);
titlestr : string;
x_axis, y_axis : string;
x_min, x_max, y_min, y_max : double;
VAR VarLabels : StrDyneVec);
procedure DynIntMatPrint(Mat: IntDyneMat; Rows, Cols: integer; YTitle: string; procedure DynIntMatPrint(Mat: IntDyneMat; Rows, Cols: integer; YTitle: string;
RowLabels, ColLabels: StrDyneVec; Title: string); overload; RowLabels, ColLabels: StrDyneVec; Title: string); overload;
@ -203,7 +199,7 @@ procedure matinv(a, vtimesw, v, w: DblDyneMat; n: integer);
implementation implementation
uses uses
StrUtils; StrUtils, Utils;
procedure GridDotProd(col1, col2: integer; out Product: double; var Ngood: integer); procedure GridDotProd(col1, col2: integer; out Product: double; var Ngood: integer);
// Get the cross-product of two vectors // Get the cross-product of two vectors
@ -416,8 +412,8 @@ end;
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Product of matrix b times c with results returned in a // Product of matrix b times c with results returned in a
procedure MatAxB(var A, B, C: DblDyneMat; BRows, BCols, CRows, CCols: Integer; procedure MatAxB(const A, B, C: DblDyneMat; BRows, BCols, CRows, CCols: Integer;
var ErrorCode: boolean); out ErrorCode: boolean);
var var
i, j, k: integer; i, j, k: integer;
begin begin
@ -1846,8 +1842,8 @@ begin
MatPrint(xmat, Rows, Cols, Title, RowLabels, ColLabels, NCases, OutputFrm.RichEdit.Lines); MatPrint(xmat, Rows, Cols, Title, RowLabels, ColLabels, NCases, OutputFrm.RichEdit.Lines);
end; end;
procedure MatPrint(var xmat: DblDyneMat; Rows, Cols: integer; var Title: string; procedure MatPrint(const xmat: DblDyneMat; Rows, Cols: integer; const Title: string;
var RowLabels, ColLabels: StrDyneVec; NCases: integer; AReport: TStrings); const RowLabels, ColLabels: StrDyneVec; NCases: integer; AReport: TStrings);
var var
i, j, first, last, nflds: integer; i, j, first, last, nflds: integer;
done: boolean; done: boolean;
@ -1950,27 +1946,20 @@ begin
end; end;
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
procedure scatplot(var x : DblDyneVec; procedure scatplot(const x, y: DblDyneVec; NoCases: integer;
var y : DblDyneVec; const TitleStr, x_axis, y_axis: string; x_min, x_max, y_min, y_max: double;
nocases : integer; const VarLabels: StrDyneVec; AReport: TStrings);
titlestr : string;
x_axis, y_axis : string;
x_min, x_max, y_min, y_max : double;
VAR VarLabels : StrDyneVec);
var var
i, j, l, row, xslot : integer; i, j, l, row, xslot : integer;
//xdelta: Double; maxy: double;
maxy: double; incrementx, incrementy, rangex, rangey, swap : double;
incrementx, incrementy, rangex, rangey, swap : double; plotstring : array[0..51,0..61] of char;
plotstring : array[0..51,0..61] of char; height : integer;
//ymed, xmed : double; overlap : boolean;
height : integer; valuestring : string[2];
overlap : boolean; howlong : integer;
valuestring : string[2]; outline : string;
howlong : integer; Labels : StrDyneVec;
outline : string;
Labels : StrDyneVec;
begin begin
Assert(OutputFrm <> nil); Assert(OutputFrm <> nil);
@ -1986,28 +1975,37 @@ begin
// ymed := rangey / 2; // ymed := rangey / 2;
{ sort in descending order } { sort in descending order }
for i := 1 to (nocases - 1) do for i := 1 to (NoCases - 1) do
begin begin
for j := (i + 1) to nocases do for j := (i + 1) to NoCases do
begin begin
if y[i-1] < y[j-1] then if y[i-1] < y[j-1] then
begin begin
Exchange(y[i-1], y[j-1]);
{
swap := y[i-1]; swap := y[i-1];
y[i-1] := y[j-1]; y[i-1] := y[j-1];
y[j-1] := swap; y[j-1] := swap;
}
Exchange(x[i-1], x[j-1]);
{
swap := x[i-1]; swap := x[i-1];
x[i-1] := x[j-1]; x[i-1] := x[j-1];
x[j-1] := swap; x[j-1] := swap;
}
Exchange(Labels[i-1], Labels[j-1]);
{
outline := Labels[i-1]; outline := Labels[i-1];
Labels[i-1] := Labels[j-1]; Labels[i-1] := Labels[j-1];
Labels[j-1] := outline; Labels[j-1] := outline;
}
end; end;
end; end;
end; end;
outline := ' SCATTERPLOT - ' + titlestr;
OutputFrm.RichEdit.Lines.Add(outline); AReport.Add(' SCATTERPLOT - ' + TitleStr);
OutputFrm.RichEdit.Lines.Add(''); AReport.Add('');
OutputFrm.RichEdit.Lines.Add(y_axis); AReport.Add(y_axis);
maxy := y_max; maxy := y_max;
for i := 1 to 60 do for i := 1 to 60 do
for j := 1 to height+1 do plotstring[j,i] := ' '; for j := 1 to height+1 do plotstring[j,i] := ' ';
@ -2019,9 +2017,7 @@ begin
row := row + 1; row := row + 1;
plotstring[row,30] := '|'; plotstring[row,30] := '|';
if (row = (height / 2)) then if (row = (height / 2)) then
begin
for i := 1 to 60 do plotstring[row,i] := '-'; for i := 1 to 60 do plotstring[row,i] := '-';
end;
for i := 1 to nocases do for i := 1 to nocases do
begin begin
if ((maxy >= y[i-1]) and (y[i-1] > (maxy - incrementy))) then if ((maxy >= y[i-1]) and (y[i-1] > (maxy - incrementy))) then
@ -2041,40 +2037,40 @@ begin
if (howlong < 2) then if (howlong < 2) then
plotstring[row,xslot] := valuestring[2] plotstring[row,xslot] := valuestring[2]
else for l := 1 to 2 do else for l := 1 to 2 do
plotstring[row,xslot + l - 1] := valuestring[l]; plotstring[row,xslot + l - 1] := valuestring[l];
end; end;
end; end;
end; end;
maxy := maxy - incrementy; maxy := maxy - incrementy;
end; end;
{ print the plot } { print the plot }
for i := 1 to row do for i := 1 to row do
begin begin
outline := ' |'; outline := ' |';
for j := 1 to 60 do outline := outline + format('%1s',[plotstring[i,j]]); for j := 1 to 60 do outline := outline + Format('%1s', [plotstring[i,j]]);
outline := outline + format('|-%6.2f-%6.2f', outline := outline + Format('|-%6.2f-%6.2f',
[(y_max - i * incrementy),(y_max - i * incrementy + incrementy)]); [(y_max - i * incrementy),(y_max - i * incrementy + incrementy)]);
OutputFrm.RichEdit.Lines.Add(outline); AReport.Add(outline);
end; end;
outline := ''; outline := '';
for i := 1 to 63 do outline := outline + '-'; for i := 1 to 63 do outline := outline + '-';
OutputFrm.RichEdit.Lines.Add(outline); AReport.Add(outline);
outline := ''; outline := '';
for i := 1 to 16 do outline := outline + ' | '; for i := 1 to 16 do outline := outline + ' | ';
outline := outline + x_axis; outline := outline + x_axis;
OutputFrm.RichEdit.Lines.Add(outline); AReport.Add(outline);
outline := ''; outline := '';
for i := 1 to 16 do outline := outline + format('%4.1f',[(x_min + i * incrementx - incrementx)]); for i := 1 to 16 do outline := outline + Format('%4.1f', [(x_min + i * incrementx - incrementx)]);
OutputFrm.RichEdit.Lines.Add(outline); AReport.Add(outline);
OutputFrm.RichEdit.Lines.Add(''); AReport.Add('');
OutputFrm.RichEdit.Lines.Add('Labels:'); AReport.Add('Labels:');
for i := 1 to nocases do for i := 1 to nocases do
begin AReport.Add('%2d = %s', [i, Labels[i-1]]);
outline := format('%2d = %s',[i,Labels[i-1]]);
OutputFrm.RichEdit.Lines.Add(outline);
end;
OutputFrm.ShowModal;
OutputFrm.RichEdit.Clear;
Labels := nil; Labels := nil;
end; { of scatplot procedure } end; { of scatplot procedure }
//------------------------------------------------------------------- //-------------------------------------------------------------------

View File

@ -9,6 +9,10 @@ uses
function AnySelected(AListbox: TListBox): Boolean; function AnySelected(AListbox: TListBox): Boolean;
procedure Exchange(var a, b: Double); overload;
procedure Exchange(var a, b: Integer); overload;
procedure Exchange(var a, b: String); overload;
implementation implementation
function AnySelected(AListBox: TListBox): Boolean; function AnySelected(AListBox: TListBox): Boolean;
@ -24,5 +28,32 @@ begin
end; end;
end; end;
procedure Exchange(var a, b: Double);
var
tmp: Double;
begin
tmp := a;
a := b;
b := tmp;
end;
procedure Exchange(var a, b: Integer);
var
tmp: Integer;
begin
tmp := a;
a := b;
b := tmp;
end;
procedure Exchange(var a, b: String);
var
tmp: String;
begin
tmp := a;
a := b;
b := tmp;
end;
end. end.