最小二乘法
算法是别的大虾写的
procedure MinSqrMul(m, n: Integer; A: TMatrix; b: array of Double; var x: array of Double);
var
i, j, k: Integer;
ATA: array of array of Double;
ATb: array of Double;
Elem: Double;
begin
SetLength(ATA, n, n);
SetLength(ATb, n);
for i := 0 to n - 1 do
for j := 0 to n - 1 do
begin
ATA[i, j] := 0;
for k := 0 to m - 1 do
ATA[i, j] := ATA[i, j] + A[k, i] * A[k, j];
end;
for i := 0 to n - 1 do
begin
ATb := 0;
for j := 0 to m - 1 do
ATb := ATb + A[j, i] * b[j];
end;
for i := 0 to n - 1 do
begin
Elem := ATA[i, i];
for j := i to n - 1 do
ATA[i, j] := ATA[i, j] / Elem;
ATb := ATb / Elem;
for k := i + 1 to n - 1 do
begin
Elem := -ATA[k, i];
for j := i + 1 to n - 1 do
ATA[k, j] := ATA[k, j] + ATA[i, j] * Elem;
ATb[k] := ATb[k] + ATb * Elem;
end;
end;
x[n - 1] := ATb[n - 1];
for i := n - 2 downto 0 do
begin
for j := i + 1 to n - 1 do
ATb := ATb - ATA[i, j] * x[j];
x := ATb;
end;
end;
procedure Tsensor.Button1Click(Sender: TObject);
var
A: TMatrix;
i, j: byte;
b: array of double;
x: array of double;
begin
setlength(A, series2.Count, 2);
Setlength(b, series2.Count);
Setlength(x, series2.Count);
for i := 1 to series2.Count do
begin
A[i - 1, 0] := series2.XValue[i - 1];
A[i - 1, 1] := 1;
b[i - 1] := series2.YValue[i - 1];
end;
MinSqrMul(series2.Count, 2, A, b, x);
series1.AddXY(series2.XValue[0], x[0] * series2.XValue[0] + x[1]);
series1.AddXY(series2.XValue[series2.Count - 1], x[0] * series2.XValue[series2.Count - 1] + x[1]);
DataModule2.cfgADOTable2.Edit;
DataModule2.cfgADOTable2.fieldbyname('A').asstring := formatfloat('0.000', x[0]);
DataModule2.cfgADOTable2.fieldbyname('B').asstring := formatfloat('0.000', x[1]);
DataModule2.cfgADOTable2.Post;
end;