求多点拟合成直线的算法,大侠帮忙!(50分)

  • 主题发起人 主题发起人 xcx227
  • 开始时间 开始时间
X

xcx227

Unregistered / Unconfirmed
GUEST, unregistred user!
有多个数据点,求由这些点拟合成直线的算法,困扰已久,救命!
 
用最小二乘法
这是数学中的曲线拟合问题
 
任取两点,计算直线
循环直至取遍所有的情况,把所得的直线各项系数取平均数,作为所得直线的系数
我猜得
 
看看数值计算的书就可以了,有专门算法的
 
拟合曲线吧?
 
呵呵,写过,找找
 
最小二乘法
算法是别的大虾写的


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;
 
我是研究线性,非线性拟合的。呵呵
这是最最简单的实现方法
Procedure Lreg(y,x:array of double;n:integer;
var a,b:double);

var
sigxy,sigx,sigy,sigxx:double;
i:integer;
begin
sigxy:=0;sigx:=0;sigy:=0;sigxx:=0;
for I := vmin to n do // Iterate
begin
sigxy:=sigxy+x*y;
sigx:=sigx+x;
sigy:=sigy+y;
sigxx:=x*x;
end; // for

b:=(sigxy-sigx*sigy/n)/(sigxx-sigx*sigx/n);
a:=(sigy-b*sigx)/n;
end;
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部