LazStats: Fix polynomial smooth in AutoCorUnit.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7432 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-05-06 17:25:42 +00:00
parent f2502d8ad3
commit bba39d0ef5
3 changed files with 28 additions and 18 deletions

View File

@ -89,6 +89,7 @@ type
FExpSmoothAlpha: Double; FExpSmoothAlpha: Double;
FMovAvgRawWeights: DblDyneVec; FMovAvgRawWeights: DblDyneVec;
FMovAvgOrder: Integer; FMovAvgOrder: Integer;
FPolyOrder: Integer;
function CalcMean(const pts: DblDyneVec; NoPts: Integer): Double; function CalcMean(const pts: DblDyneVec; NoPts: Integer): Double;
procedure ExponentialSmooth(var Pts: DblDyneVec; NoPts: Integer); procedure ExponentialSmooth(var Pts: DblDyneVec; NoPts: Integer);
procedure Four1(var data: DblDyneVec; nn: LongWord; isign: integer); procedure Four1(var data: DblDyneVec; nn: LongWord; isign: integer);
@ -97,7 +98,7 @@ type
procedure GetPts(var pts: DblDyneVec; var NoPts: Integer; DepVar: Integer); procedure GetPts(var pts: DblDyneVec; var NoPts: Integer; DepVar: Integer);
procedure MovingAverage(var Pts: DblDyneVec; NoPts: Integer); procedure MovingAverage(var Pts: DblDyneVec; NoPts: Integer);
procedure PlotDifferencesForLag(var Pts: DblDyneVec; NoPts: Integer); procedure PlotDifferencesForLag(var Pts: DblDyneVec; NoPts: Integer);
procedure PolyFit(const pts: DblDyneVec; var avg: DblDyneVec; NoPts: integer); procedure PolyFit(const pts: DblDyneVec; var avg: DblDyneVec; NoPts, Order: integer);
procedure PolynomialSmooth(var Pts: DblDyneVec; NoPts: Integer); procedure PolynomialSmooth(var Pts: DblDyneVec; NoPts: Integer);
procedure RealFT(var data: DblDyneVec; n: LongWord; isign: integer); procedure RealFT(var data: DblDyneVec; n: LongWord; isign: integer);
procedure RemoveMeans(var Pts: DblDyneVec; NoPts: Integer; AMean: Double); procedure RemoveMeans(var Pts: DblDyneVec; NoPts: Integer; AMean: Double);
@ -154,6 +155,7 @@ begin
FMovAvgOrder := 1; FMovAvgOrder := 1;
FMovAvgRawWeights := nil; FMovAvgRawWeights := nil;
FExpSmoothAlpha := 0.99; FExpSmoothAlpha := 0.99;
FPolyOrder := 1;
UpdateBtnStates; UpdateBtnStates;
end; end;
@ -202,7 +204,7 @@ procedure TAutoCorrFrm.FormCreate(Sender: TObject);
begin begin
Assert(OS3MainFrm <> nil); Assert(OS3MainFrm <> nil);
if PointsFrm = nil then Application.CreateForm(TPointsFrm, PointsFrm); if PointsFrm = nil then Application.CreateForm(TPointsFrm, PointsFrm);
FExpSmoothAlpha := 0.99;
ResetBtnClick(self); ResetBtnClick(self);
end; end;
@ -890,23 +892,22 @@ begin
end; end;
procedure TAutoCorrFrm.PolyFit(const pts: DblDyneVec; var avg: DblDyneVec; procedure TAutoCorrFrm.PolyFit(const pts: DblDyneVec; var avg: DblDyneVec;
NoPts: integer); NoPts, Order: integer);
var var
X: DblDyneMat; X: DblDyneMat;
XY: DblDyneVec; XY: DblDyneVec;
XTX: DblDyneMat; XTX: DblDyneMat;
Beta: DblDyneVec; Beta: DblDyneVec;
t, Yhat: double; t, Yhat: double;
i, j, k, order: integer; i, j, k: integer;
RowLabels, ColLabels: StrDyneVec; RowLabels, ColLabels: StrDyneVec;
begin begin
order := StrToInt(PolynomialFrm.PolyEdit.Text); SetLength(X, NoPts, order+1);
SetLength(X,NoPts,order+1); SetLength(XTX, order+2, order+2);
SetLength(XTX,order+2,order+2); SetLength(XY, order+1);
SetLength(XY,order+1); SetLength(Beta, order+1);
SetLength(Beta,order+1); SetLength(RowLabels, NoPts+1);
SetLength(RowLabels,NoPts+1); SetLength(ColLabels, NoPts+1);
SetLength(ColLabels,NoPts+1);
// initialize // initialize
for i := 0 to NoPts - 1 do for i := 0 to NoPts - 1 do
@ -1424,9 +1425,12 @@ var
begin begin
F := TPolynomialFrm.Create(nil); F := TPolynomialFrm.Create(nil);
try try
F.Order := FPolyOrder;
if F.ShowModal <> mrOK then if F.ShowModal <> mrOK then
exit; exit;
FPolyOrder := F.Order;
if ProjectChk.Checked then if ProjectChk.Checked then
noProj := StrToInt(ProjPtsEdit.Text) noProj := StrToInt(ProjPtsEdit.Text)
else else
@ -1442,7 +1446,7 @@ begin
end; end;
end; end;
PolyFit(pts, avg, NoPts + noproj); PolyFit(pts, avg, NoPts + noproj, FPolyOrder);
// plot original and smoothed data // plot original and smoothed data
PointsFrm.pts := pts; PointsFrm.pts := pts;

View File

@ -9,7 +9,6 @@ object PolynomialFrm: TPolynomialFrm
ClientHeight = 99 ClientHeight = 99
ClientWidth = 351 ClientWidth = 351
OnActivate = FormActivate OnActivate = FormActivate
OnShow = FormShow
Position = poMainFormCenter Position = poMainFormCenter
LCLVersion = '2.1.0.0' LCLVersion = '2.1.0.0'
object CancelBtn: TButton object CancelBtn: TButton
@ -76,9 +75,9 @@ object PolynomialFrm: TPolynomialFrm
Top = 16 Top = 16
Width = 152 Width = 152
AutoSize = True AutoSize = True
BorderSpacing.Left = 100 BorderSpacing.Left = 32
BorderSpacing.Top = 16 BorderSpacing.Top = 16
BorderSpacing.Right = 100 BorderSpacing.Right = 32
BorderSpacing.Bottom = 8 BorderSpacing.Bottom = 8
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 23 ClientHeight = 23

View File

@ -22,13 +22,15 @@ type
PolyEdit: TEdit; PolyEdit: TEdit;
Label1: TLabel; Label1: TLabel;
procedure FormActivate(Sender: TObject); procedure FormActivate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure HelpBtnClick(Sender: TObject); procedure HelpBtnClick(Sender: TObject);
procedure OKBtnClick(Sender: TObject); procedure OKBtnClick(Sender: TObject);
private private
{ private declarations } { private declarations }
function GetOrder: Integer;
procedure SetOrder(const AValue: Integer);
public public
{ public declarations } { public declarations }
property Order: Integer read GetOrder write SetOrder;
end; end;
var var
@ -51,9 +53,9 @@ begin
OKBtn.Constraints.MinWidth := w; OKBtn.Constraints.MinWidth := w;
end; end;
procedure TPolynomialFrm.FormShow(Sender: TObject); function TPolynomialFrm.GetOrder: Integer;
begin begin
PolyEdit.Text := '1'; Result := StrToInt(PolyEdit.Text);
end; end;
procedure TPolynomialFrm.HelpBtnClick(Sender: TObject); procedure TPolynomialFrm.HelpBtnClick(Sender: TObject);
@ -81,6 +83,11 @@ begin
end; end;
end; end;
procedure TPolynomialFrm.SetOrder(const AValue: Integer);
begin
PolyEdit.Text := IntToStr(AValue);
end;
initialization initialization
{$I polynomialunit.lrs} {$I polynomialunit.lrs}