拟合平滑回归分析
程序模块图
设计模块图
由于程序中的注释做得全面,方便了解程序模块的意义。
unit U_MultiLineRegress;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, Menus, jpeg, Grids,U_RollFont,
StrUtils,Math, DB, ADODB, Buttons, ToolWin, IniFiles,U_parsor, ComOBJ,
ExcelXP, Printers, Registry, shellapi;
type
TF_MultiLineRegress = class(TForm)
StatusBar1: TStatusBar;
Panel1: TPanel;
Image1: TImage;
Panel2: TPanel;
Panel3: TPanel;
Label100: TLabel;
ProgressBar1: TProgressBar;
OpenDialog1: TOpenDialog;
ADOTable1: TADOTable;
Panel4: TPanel;
ToolBar1: TToolBar;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
SpeedButton4: TSpeedButton;
SpeedButton5: TSpeedButton;
SpeedButton6: TSpeedButton;
Panel5: TPanel;
GroupBox1: TGroupBox;
Button1: TButton;
StringGrid1: TStringGrid;
Button2: TButton;
GroupBox2: TGroupBox;
Memo1: TMemo;
Button4: TButton;
Button5: TButton;
Button6: TButton;
SaveDialog1: TSaveDialog;
Label1: TLabel;
Label2: TLabel;
PrintDialog1: TPrintDialog;
Panel6: TPanel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Panel7: TPanel;
Label7: TLabel;
Button7: TButton;
Button8: TButton;
Button3: TButton;
Timer1: TTimer;
Bevel1: TBevel;
Label3: TLabel;
Label8: TLabel;
Image2: TImage;
Bevel2: TBevel;
procedure Label7Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure Button8Click(Sender: TObject);
procedure SpeedButton5Click(Sender: TObject);
procedure SpeedButton4Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure SpeedButton2Click(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton6Click(Sender: TObject);
procedure SpeedButton3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormResize(Sender: TObject);
Type TCoordiateRecord=record //定义二维坐标记录类型
xscreen:integer; //在屏幕上画的屏幕坐标点
zscreen:integer;
end;
Type matrx2=Array of Array of Double; //定义二维数组类matrx2
private
X_num,Y_num,Z_num,X_0,Z_0:integer;//单位坐标像素值,坐标原点在屏幕位置像素值
y_Axis:Boolean; //T为画Y轴,即Y轴上的标刻方向全向上,F为画其它轴,标刻方向另取
k:integer;//实验值序号
drawK:Boolean; //表示曲线是否画出
RunNum:smallint; //运行次数,未注册用户只有用20次
err_num:smallint; //输入密码次数
NoRegistry:Boolean; //没有注册开关
LoginCode:shortstring; //注册码
MachineCode0,MachineCode1:string; //机器码
{ Private declarations }
//自定义星期函数
Function f_get_week:shortString;
Procedure ReadWriteIniFile;//读写初始文件
procedure OpenChildForm(FormClass:TFormClass;var Fm;AOwner:TComponent);
procedure CoordInitValue;//计算坐标初始值
function WorldToScreen(var xworld,yworld,zworld:Double):TCoordiateRecord;//世界坐标转为屏幕坐标函数
procedure DrawLine(var x1world,y1world,z1world,x2world,y2world,z2world:Double);//画线段过程
procedure ArrowHead(var x1world,y1world,z1world,x2world,y2world,z2world:Double);//画箭头过程
procedure Scale(var x1world,y1world,z1world,//画刻度及标尺过程
x2world,y2world,z2world:Double;a,b:smallint);//a,b是线段画刻度的起始值
procedure WriteCoordinateName(var xworld,yworld,zworld:Double;
Ax,Ay:smallint;char:shortstring);//写坐标轴标识字过程
procedure BackGroundColor; //画背景颜色
procedure Draw2DCoordinate; //画二维坐标
procedure Draw3DCoordinate; //画三维坐标
procedure DrawMultiCurve(Expre:string;CurveColor:TColor);//画多项式表达式曲线
procedure DrawFoldLine(StrGrd:TStringGrid;Col:integer;Color:TColor);//画五点三次平滑数据点的折线
procedure DrawDataCross(StrGrd:TStringGrid);//将StrGrd中的数据用' '号画出来
procedure InputTextDocm(StringGrid:TStringGrid);
function ChEnCharLen(Str:string):integer;
procedure InputExcelDocm(ADOTable:TADOTable;
ExcelSheet:shortstring;StringGrid:TStringGrid);
procedure InputAccessDocm(ADOTable:TADOTable;
AccessSheet:shortstring;StringGrid:TStringGrid);//录入ACCESS表记录
procedure InputSQLDocm(ADOTable:TADOTable;
SQLSheet:shortstring;StringGrid:TStringGrid);//录入SQLServer表记录
procedure DrawCrossLine(var xworld,yworld,zworld:Double;Color:TColor);//把实验数据点画为‘ ‘号
procedure PrintConic;//打印显示曲线过程
procedure PrintMemoData(Memo:TMemo);//打印分析结果过程
Procedure LoginInitialize;//注册初始值
Procedure ReadRegistry;//读注册表过程
Procedure WriteRegistry;//写注册表过程
function Serial(Num:DWORD):string;//加密函数
procedure LeastQudricCurveJoin(N,P:integer); //最小二乘曲线拟合
procedure LeastQudricFaceJoin(N,M,P,Q:integer); //最小二乘曲面拟合
procedure CheBySheV(N,P:integer); //切比雪夫曲线拟合
procedure Remez(N:integer;A,B:Double); //最佳一致逼近
procedure FiveThreeSmooth(StrGrd:TStringGrid;ColRead,ColWrite:integer);//五点三次平滑
procedure OneLineRegress(StrGrd:TStringGrid); //一元线性回归分析
procedure MulLineRegress(StrGrd:TStringGrid); //多元线性回归
procedure StepRegress(StrGrd:TStringGrid;F1,F2,E:Double);//逐步回归
procedure StrGrdDeleteRow(StrGrd:TStringGrid); //在StringGrid表格中删除行
procedure StrGrdInsertRow(StrGrd:TStringGrid); //在StringGrid表格中插入行
procedure StrGrdToText( //StringGrid保存为文本
StrGrd:TStringGrid; //转换成文本的StringGrid表格
DocmName:Shortstring); //转换成文本的表头标题名
procedure StrGrdToExcel( //StringGrid转换成Excel表显示
StrGrd:TStringGrid; //转换成Excel的StringGrid表格
DocmName:Shortstring); //转换成Excel表的标题名
public //TTowArray
CoordX_min,CoordX_max:Double;//X坐标范围
CoordY_min,CoordY_max:Double;//Y坐标范围
CoordZ_min,CoordZ_max:Double;//Z坐标范围
DrawX_min,DrawX_max:Double; //X绘图范围
DrawY_min,DrawY_max:Double; //Y绘图范围
DrawZ_min,DrawZ_max:Double; //Z绘图范围
DrawX_step,DrawY_step:integer; //X,Y方向网格宽
CoordXY_Angle:Double; //坐标XY夹角
Width1,Width2,Width3:Smallint; //坐标曲线线宽
Color1,Color2,Color3,Color4:TColor;//背景坐标曲线数据颜色
Variable_Num:shortint;//多元线性方程的变量个数,2变量(二维坐标),3变量(三维坐标)
Record_Num:integer; //实验记录条数
AnalysSel:shortstring;//拟合平滑回归选择:a最小二乘曲线拟合,b最小二乘曲面拟合
//c切比雪夫曲线拟合,d最佳一致逼近平滑,e一元线性回归,
//f二或多元线性回归,g逐步回归,h五点三次平滑
DataPoint_X,DataPoint_Y:integer;//实验数据点个数
Degree_X,Degree_Y:integer; //拟合多项式中X,Y最高次幂数 1;
Area_X,Area_Y:Double; //最佳一致逼近函数取值区间
Precision:Double; //最佳一致逼近中多项式与函数的精度
B_DrawFunc,B_DrawMult:Boolean;//画模拟函数和拟合多项式图
func:string; //参考模拟函数
X_Average,Y_Average:Boolean; //分析中为防溢出取X,Y变量平均值
SheetName:String; //一次性调入数据文件的数据表名
Test_F1,Test_F2:Double; //选入或剔除因子显著性检验值F1,F2
B_AnalysSel:Boolean; //分析选择开关,只有使用了"分析选择"才能运行"执行操作"
AnalyseSelect_k:Boolean; //表示AnalyseSelect子窗口是否打开
{ Public declarations }
procedure StrGrdChang(StrGrd:TStringGrid);//StringGrid列变
procedure InputFileData;//文件调入数据子过程
end;
var
F_MultiLineRegress: TF_MultiLineRegress;
implementation
uses U_AnalyseSelect,U_CoordSet,U_FileDataInput, CPUID;
var TRollThread:TRollFontThread;//创建滚动字符线程一个新线和TRollThread
{$R *.dfm}
//坐标设置
procedure TF_MultiLineRegress.SpeedButton1Click(Sender: TObject);
begin
OpenChildForm(TF_CoordSet,F_coordSet,self);
end;
//分析选择按钮
procedure TF_MultiLineRegress.SpeedButton2Click(Sender: TObject);
begin
OpenChildForm(TF_AnalyseSelect,F_AnalyseSelect,self);
end;
//执行操作按钮
procedure TF_MultiLineRegress.SpeedButton3Click(Sender:TObject);
var N,M,P,Q,Col:integer;
i,j,w:integer;
E,X,Y:Double;
XX,YY:Array of Double;
begin
if B_AnalysSel=False then
begin
if Application.MessageBox('您还没有选择您所需要分析的内容!'
#13 '是否需要打开“分析选择”窗口?','系统提示',
MB_IconInformation MB_YesNo)=mrYes then
begin
B_AnalysSel:=False;
SpeedButton2.Click;
end;
Exit;
end;
B_AnalysSel:=False; //分析选择开关,只有使用了"分析选择"才能运行"执行操作"
drawK:=True; //表示已经绘图
Image1.Picture:=nil; //清空画面,便于再画
BackGroundColor; //画背景颜色
if AnalysSel='a' then //1最小二乘曲线拟合
begin
Draw2DCoordinate; //画二维坐标
//最小二乘曲线拟合子过程赋值
N:=DataPoint_X; //多项式X实验数据个数
P:=Degree_X 1; //X项最高次数幂,即线性多项式项数
StringGrid1.RowCount:=N 1;
E:=0;
for i:=1 to N do
begin
StringGrid1.Cells[0,i]:=inttostr(i);
X:=0.1*(i-1);
StringGrid1.Cells[1,i]:=floattostr(X);
Y:=X-exp(-X);
StringGrid1.Cells[2,i]:=floattostr(Y);
DrawCrossLine(X,E,Y,Color4);//把实验数据点画为‘ ‘号
end;
//调用最小二乘曲线拟合子过程
LeastQudricCurveJoin(N,P);
end else if AnalysSel='b' then //2最小二乘曲面拟合
begin
Draw3DCoordinate; //画三维坐标
//最小二乘曲面拟合子过程赋值
N:=DataPoint_X; //多项式X实验数据个数
M:=DataPoint_Y; //多项式Y实验数据个数
P:=Degree_X 1; //多项式X项最高次数幂
Q:=Degree_Y 1; //多项式Y项最高次数幂
SetLength(XX,N);SetLength(YY,M);
StringGrid1.RowCount:=N*M 1;
for i:=1 to N do
begin
XX[i]:=0.2*(i-1);
StringGrid1.Cells[1,i]:=floattostr(XX[i]);
end;
for i:=1 to M do
begin
YY[i]:=0.1*(i-1);
StringGrid1.Cells[2,i]:=floattostr(YY[i]);
end;
w:=0;
for i:=1 to N do
begin
for j:=1 to M do
begin
w:=w 1;
StringGrid1.Cells[0,w]:=inttostr(w);
StringGrid1.Cells[3,w]:=floattostr(exp(XX[i]*XX[i]-YY[j]*YY[j]));
end;
end;
//调用最小二乘曲面拟合子过程
LeastQudricFaceJoin(N,M,P,Q);
end else if AnalysSel='c' then //3切比雪夫曲线拟合
begin
Draw2DCoordinate; //画二维坐标
//切比雪夫子过程赋值
N:=DataPoint_X; //多项式X实验数据个数
P:=Degree_X 1; //多项式项数,最高次数幂为P-1
//取拟合数据到表
StringGrid1.RowCount:=N 1;
E:=0;
for i:=1 to N do
begin
StringGrid1.Cells[0,i]:=inttostr(i);
X:=-6 0.6*(i-1);
StringGrid1.Cells[1,i]:=floattostr(X);
Y:=arctan(X);
StringGrid1.Cells[2,i]:=floattostr(Y);
DrawCrossLine(X,E,Y,Color4);//把实验数据点画为‘ ‘号
end;
//切比雪夫曲线拟合
CheBySheV(N,P);
end else if AnalysSel='d' then //4最佳一致逼近米兹方法
begin
Draw2DCoordinate; //画二维坐标
X:=Area_X; //函数取值左区间
Y:=Area_Y; //函数取值右区间
N:=Degree_X 1; //逼近多项式最大幂指数
Remez(N,X,Y); //调用最佳一致逼近米兹方法
end else if AnalysSel='e' then //5一元线性回归
begin
Draw2DCoordinate; //画二维坐标
DrawDataCross(StringGrid1);//将StrGrd中的数据用' '号画出来
OneLineRegress(StringGrid1);//调用一元线性回归
end else if AnalysSel='f' then //6多元线性回归
begin
Draw3DCoordinate; //画三维坐标
DrawDataCross(StringGrid1);//将StrGrd中的数据用' '号画出来
MulLineRegress(StringGrid1); //调用多元线性回归
end else if AnalysSel='g' then //7逐步回归(三维以上)
begin
Draw3DCoordinate; //画三维坐标
DrawDataCross(StringGrid1);//将StrGrd中的数据用' '号画出来
StepRegress(StringGrid1,Test_F1,Test_F2,Precision);//调用逐步回归
end else if AnalysSel='h' then //8五点三次平滑分析
begin
Draw2DCoordinate; //画二维坐标
//调用五点三次平滑分析
P:=1;
Q:=2;
FiveThreeSmooth(StringGrid1,P,Q);
Col:=P; //画实验数据折线
DrawFoldLine(StringGrid1,Col,Color4);
Col:=Q; //画平滑数据折线
DrawFoldLine(StringGrid1,Col,Color3);
Memo1.Lines.Append('五点三次平滑分析结果:');
Memo1.Lines.Append('绿色折线是实验数据折线!');
Memo1.Lines.Append('红色折线是平滑数据折线!');
end;
end;
//1最小二乘曲线拟合 DT1,DT2,DT3输出参数,分别是拟合多项式与数据点偏差的平方和、绝对值和、绝对值最大值
procedure TF_MultiLineRegress.LeastQudricCurveJoin(N,P:integer);
var i,j,v:integer;//N拟合数据个数,M拟合多项式项数
X,Y,A,B,S,T:Array of Double; //8字节浮点变量
Z,D1,R,C,D2,G,Q,DT,DT1,DT2,DT3:Double;
Xd,Exd,flag,Expr,strtemp:string;//最后写多项式表达式时的临时变量
begin
//为动态数据开辟内存
SetLength(X,N 1);
SetLength(Y,N 1);
SetLength(A,P 1);
SetLength(B,N 1);
SetLength(S,N 1);
SetLength(T,N 1);
//从表上取拟合数据到变量
for i:=1 to N do
begin
X[i]:=strtofloat(StringGrid1.Cells[1,i]);
Y[i]:=strtofloat(StringGrid1.Cells[2,i]);
end;
//开始拟合
Q:=0;
Z:=0;
if X_Average=True then for i:=1 to N do Z:=Z X[i];//防溢出取自变量平均值Z
Z:=Z/N;
B[1]:=1;
D1:=N;
R:=0;
C:=0;
for i:=1 to N do
begin
R:=R X[i]-Z;
C:=C Y[i];
end;
C:=C/D1;
R:=R/D1;
A[1]:=C*B[1];
if P>1 then
begin
T[2]:=1;
T[1]:=-R;
D2:=0;
C:=0;
G:=0;
for i:=1 to N do
begin
Q:=X[i]-Z-R;
D2:=D2 Q*Q;
C:=Y[i]*Q C;
G:=(X[i]-Z)*Q*Q G;
end;
C:=C/D2;
R:=G/D2;
Q:=D2/D1;
D1:=D2;
A[2]:=C*T[2];
A[1]:=C*T[1] A[1];
end;
for j:=3 to P do
begin
S[j]:=T[j-1];
S[j-1]:=-R*T[j-1] T[j-2];
if j>=4 then
begin
v:=j-2;
while v>=2 do
begin
S[v]:=-R*T[v] T[v-1]-Q*B[v];
v:=v-1;
end;
end;
S[1]:=-R*T[1]-Q*B[1];
D2:=0;
C:=0;
G:=0;
for i:=1 to N do
begin
Q:=S[j]; //j
v:=j-1;
while v>=1 do
begin
Q:=Q*(X[i]-Z) S[v];
v:=v-1;
end;
D2:=D2 Q*Q;
C:=Y[i]*Q C;
G:=(X[i]-Z)*Q*Q G;
end;
C:=C/D2;
R:=G/D2;
Q:=D2/D1;
D1:=D2;
A[j]:=C*S[j];
T[j]:=S[j];
v:=j-1;
while v>=1 do
begin
A[v]:=C*S[v] A[v];
B[v]:=T[v];
T[v]:=S[v];
v:=v-1;
end;
end;
DT1:=0;
DT2:=0;
DT3:=0;
for i:=1 to N do
begin
Q:=A[P];
v:=P-1;
while v>=1 do
begin
Q:=Q*(X[i]-Z) A[v];
v:=v-1;
end;
DT:=Q-Y[i];
if abs(DT)>DT3 then DT3:=abs(DT);
DT1:=DT1 DT*DT;
DT2:=DT2 abs(DT);
end;
//绘拟合后的多项式表达式
Expr:=floattostr(A[1]);
Xd:='';
for i:=2 to P do
begin
if A[i]>0 then
begin
flag:=' ';
//不取平均值,取平均值的不同表达式
if X_Average=False then Xd:=Xd '*x' else Xd:=Xd '*(x-' floattostr(Z) ')';
Exd:=floattostr(A[i]) Xd;
Expr:=Expr flag Exd;
end else if A[i]<0 then
begin
flag:='';
if X_Average=False then Xd:=Xd '*x' else Xd:=Xd '*(x-' floattostr(Z) ')';
//Xd:=Xd '*x';
Exd:=floattostr(A[i]) Xd;
Expr:=Expr flag Exd;
end;
end;
//显示拟合后的结果
Memo1.Lines.Append('最小二乘曲线拟合');
Memo1.Lines.Append('标准多项式:P(x)=A[1] A[2](x-x0) A[3](x-x0)^2 … A[M 1](x-x0)^M');
Memo1.Lines.Append('其中平均值:x0=(x1 x2 … xN)/N=' floattostr(Z));
Memo1.Lines.Append('拟合多项式表达式如下:');
Memo1.Lines.Append('F(x)=' Expr ';');
for i:=1 to P do
begin //Memo中字符串之间不能夹插变量,变量之间不能夹插字符串输出,用strtemp变通
strtemp:=inttostr(i) ']:' floattostr(A[i]);
Memo1.Lines.Append('多项式系数A[' strtemp);
end;
Memo1.Lines.Append('多项式与数据点偏差平方和:' floattostr(DT1));
Memo1.Lines.Append('多项式与数据点偏差绝对值和:' floattostr(DT2));
Memo1.Lines.Append('多项式与数据点偏差绝对值最大值:' floattostr(DT3));
Memo1.Lines.Append('拟合函数式:f(x)=' func);
//将Expr表达式绘出曲线并与函数f(x)曲线比较
if B_DrawFunc=True then DrawMultiCurve(func,Color4);//画函数曲线
if B_DrawMult=True then DrawMultiCurve(Expr,Color3);//画多项式表达式曲线
end;
//2最小二乘曲面拟合
procedure TF_MultiLineRegress.LeastQudricFaceJoin(N,M,P,Q:integer);
var X,Y,APX,APY,BX,BY,T,T1,T2:Array of Double;//定义一维动态数组
A,U,V,Z:Array of Array of Double; //定义二维动态数组
XX,YY,D1,D2,G,G1,G2,X1,X2,Y1,DD,DT:Double;
DT1,DT2,DT3:Double;
i,j,w,f,h:integer;
flag:shortstring;//多项式系数A的加减号
//最后写多项式表达式时的临时变量
Xd,Yd,EXd,Expry,Exprx,Exprxy,Expr,strtemp:string;
begin
//给动态数组内存空间
SetLength(X,N 1); SetLength(Y,M 1); //给一维动态数组分配内存,从0开始
SetLength(APX,M); SetLength(APY,M);
SetLength(BX,M); SetLength(BY,M);
SetLength(T,M); SetLength(T1,M);
SetLength(T2,M);
SetLength(Z,N 1,M 1); SetLength(A,P 1,Q 1);//给二维动态数组分配内存,从0开始
SetLength(U,M,M); SetLength(V,M,M 1);
//将实验数据给变量
for i:=1 to N do X[i]:=strtofloat(StringGrid1.Cells[1,i]);
for i:=1 to M do Y[i]:=strtofloat(StringGrid1.Cells[2,i]);
w:=0;
for i:=1 to N do
begin
for j:=1 to M do
begin
w:=w 1;
Z[i,j]:=strtofloat(StringGrid1.Cells[3,w]); //给二维数组Z元素赋值
end;
end;
//执行最小二乘曲面拟合
G:=1;
XX:=0;
if X_Average=True then for i:=1 to N do XX:=XX X[i];//为防溢出求X变量平均值
XX:=XX/N;
yy:=0;
if Y_Average=True then for i:=1 to M do YY:=YY Y[i];//为防溢出求Y变量平均值
YY:=YY/M;
D1:=N;
APX[1]:=0;
for i:=1 to N do APX[1]:=APX[1] X[i]-XX;
APX[1]:=APX[1]/D1;
for j:=1 to M do
begin
V[1,j]:=0;
for i:=1 to N do V[1,j]:=V[1,j] Z[i,j];
V[1,j]:=V[1,j]/D1;
end;
if P>1 then
begin
D2:=0;
APX[2]:=0;
for i:=1 to N do
begin
G:=X[i]-XX-APX[1];
D2:=D2 G*G;
APX[2]:=APX[2] (X[i]-XX)*G*G;
end;
APX[2]:=APX[2]/D2;
BX[2]:=D2/D1;
for j:=1 to M do
begin
V[2,j]:=0;
for i:=1 to N do
begin
G:=X[i]-XX-APX[1];
V[2,j]:=V[2,j] Z[i,j]*G;
end;
V[2,j]:=V[2,j]/D2;
end;
D1:=D2;
end;
for w:=3 to P do
begin
D2:=0;
APX[w]:=0;
for j:=1 to M do V[w,j]:=0;
for i:=1 to N do
begin
G1:=1;
G2:=X[i]-XX-APX[1];
for j:=3 to w do
begin
G:=(X[i]-XX-APX[j-1])*G2-BX[j-1]*G1;
G1:=G2;
G2:=G;
end;
D2:=D2 G*G;
APX[w]:=APX[w] (X[i]-XX)*G*G;
for j:=1 to M do V[w,j]:=V[w,j] Z[i,j]*G;
end;
for j:=1 to M do V[w,j]:=V[w,j]/D2;
APX[w]:=APX[w]/D2;
BX[w]:=D2/D1;
D1:=D2;
end;
D1:=M;
APY[1]:=0;
for i:=1 to M do APY[1]:=APY[1] Y[i]-YY;
APY[1]:=APY[1]/D1;
for j:=1 to P do
begin
U[j,1]:=0;
for i:=1 to M do U[j,1]:=U[j,1] V[j,i];
U[j,1]:=U[j,1]/D1;
end;
if Q>1 then
begin
D2:=0;
APY[2]:=0;
for i:=1 to M do
begin
G:=Y[i]-YY-APY[1];
D2:=D2 G*G;
APY[2]:=APY[2] (Y[I]-YY)*G*G;
end;
APY[2]:=APY[2]/D2;
BY[2]:=D2/D1;
for j:=1 to P do
begin
U[j,2]:=0;
for i:=1 to M do
begin
G:=Y[i]-YY-APY[1];
U[j,2]:=U[j,2] V[j,i]*G;
end;
U[j,2]:=U[j,2]/D2;
end;
D1:=D2;
end;
for w:=3 to Q do
begin
D2:=0;
APY[w]:=0;
for j:=1 to P do U[j,w]:=0;
for i:=1 to M do
begin
G1:=1;
G2:=Y[i]-YY-APY[1];
for j:=3 to w do
begin
G:=(Y[i]-YY-APY[j-1])*G2-BY[j-1]*G1;
G1:=G2;
G2:=G;
end;
D2:=D2 G*G;
APY[w]:=APY[w] (Y[i]-YY)*G*G;
for j:=1 to P do U[j,w]:=u[j,w] v[j,i]*G;
end;
for j:=1 to P do U[j,w]:=U[j,w]/D2;
APY[w]:=APY[w]/D2;
BY[w]:=D2/D1;
D1:=D2;
end;
V[1,1]:=1;
V[2,1]:=-APY[1];
V[2,2]:=1;
for i:=1 to P do for j:=1 to Q do A[i,j]:=0;
for i:=3 to Q do
begin
V[i,i]:=V[i-1,i-1];
V[i,i-1]:=-APY[i-1]*V[i-1,i-1] V[i-1,i-2];
if i>=4 then
begin
w:=i-2;
while w>=2 do
begin
V[i,w]:=-APY[i-1]*V[i-1,w] V[i-1,w-1]-BY[i-1]*V[i-2,w];
w:=w-1;
end;
end;
V[i,1]:=-APY[i-1]*V[i-1,1]-BY[i-1]*V[i-2,1];
end;
for i:=1 to P do
begin
if i=1 then
begin
T[1]:=1;
T1[1]:=1;
end else if i=2 then
begin
T[1]:=-APX[1];
T[2]:=1;
T2[1]:=T[1];
T2[2]:=T[2];
end else
begin
T[i]:=T2[i-1];
T[i-1]:=-APX[i-1]*T2[i-1] T2[i-2];
if i>=4 then
begin
w:=i-2;
while w>=2 do
begin
T[w]:=-APX[i-1]*T2[w] T2[w-1]-BX[i-1]*T1[w];
w:=w-1;
end;
end;
T[1]:=-APX[i-1]*T2[1]-BX[i-1]*T1[1];
T2[i]:=T[i];
w:=i-1;
while w>=1 do
begin
T1[w]:=T2[w];
T2[w]:=T[w];
w:=w-1;
end;
end;
for j:=1 to Q do
begin
w:=i;
while w>=1 do
begin
f:=j;
while f>=1 do
begin
A[w,f]:=A[w,f] U[i,j]*T[w]*V[j,f];
f:=f-1;
end;
w:=w-1;
end;
end;
end;
DT1:=0;
DT2:=0;
DT3:=0;
for i:=1 to N do
begin
X1:=X[i]-XX;
for j:=1 to M do
begin
Y1:=Y[j]-YY;
X2:=1;
DD:=0;
for w:=1 to P do
begin
G:=A[w,Q];
h:=Q-1;
while h>=1 do
begin
G:=G*Y1 A[w,h];
h:=h-1;
end;
G:=G*X2;
DD:=DD G;
X2:=X2*X1;
end;
DT:=DD-Z[i,j];
if (abs(DT)>DT3) then DT3:=abs(DT);
DT1:=DT1 DT*DT;
DT2:=DT2 abs(DT);
end;
end;
//绘拟合后的多项式表达式(这里的P,Q都已加1)
//求多项式的A[1,2]y A[1,3]y^2 .. A[1,Q]y^(Q-1)部分Expry
Xd:='';
Expry:='';
for j := 2 to Q do
begin
if A[1,j]>0 then
begin
flag:=' ';
//取平均值的不同表达式
if X_Average=False then Xd:=Xd '*y' else Xd:=Xd '*(y-' floattostr(YY) ')';
//Xd:=Xd '*y';
Exd:=floattostr(A[1,j]) Xd;
Expry:=Expry flag Exd;
end else if A[1,j]<0 then
begin
flag:='';
if X_Average=False then Xd:=Xd '*y' else Xd:=Xd '*(y-' floattostr(YY) ')';
//Xd:=Xd '*y';
Exd:=floattostr(A[1,j]) Xd;
Expry:=Expry flag Exd;
end;
end;
//求多项的A[2,1]x A[3,1]x^2 .. A[p,1]x^(p-1)部分Exprx
Xd:='';
Exprx:='';
for i:=2 to P do
begin
if A[i,1]>0 then
begin
flag:=' ';
//取平均值的不同表达式
if X_Average=False then Xd:=Xd '*x' else Xd:=Xd '*(x-' floattostr(XX) ')';
//Xd:=Xd '*x';
Exd:=floattostr(A[i,1]) Xd;
Exprx:=Exprx flag Exd;
end else if A[i,1]<0 then
begin
flag:='';
if X_Average=False then Xd:=Xd '*x' else Xd:=Xd '*(x-' floattostr(XX) ')';
//Xd:=Xd '*x';
Exd:=floattostr(A[i,1]) Xd;
Exprx:=Exprx flag Exd;
end;
end;
//求多项式的A[2,2]x*y A[2,3]x*y^2 .. A[2,Q]x*y^(Q-1) A[3,2]x^2*y A[3,3]x^2*y^2 .. A[3,Q]x^2*y^(Q-1) ..
Xd:='';
Exprxy:='';
for i:=2 to P do
begin
//取平均值的不同表达式
if X_Average=False then Xd:=Xd '*x' else Xd:=Xd '*(x-' floattostr(XX) ')';
//Xd:=Xd '*x';
Yd:='';
for j:=2 to Q do
begin
if A[i,j]>0 then
begin
flag:=' ';
//取平均值的不同表达式
if j=2 then
begin
if X_Average=False then Yd:=Yd Xd '*y' else Yd:=Yd Xd '*(x-' floattostr(YY) ')';
end else
begin
if X_Average=False then Yd:=Yd '*y' else Yd:=Yd '*(x-' floattostr(YY) ')';
end;
//if j=2 then Yd:=Yd Xd '*y' else Yd:=Yd '*y';
Exd:=floattostr(A[i,j]) Yd;
Exprxy:=Exprxy flag Exd;
end else if A[i,j]<0 then
begin
flag:='';
//取平均值的不同表达式
if j=2 then
begin
if X_Average=False then Yd:=Yd Xd '*y' else Yd:=Yd Xd '*(x-' floattostr(YY) ')';
end else
begin
if X_Average=False then Yd:=Yd '*y' else Yd:=Yd '*(x-' floattostr(YY) ')';
end;
//if j=2 then Yd:=Yd Xd '*y' else Yd:=Yd '*y';
Exd:=floattostr(A[i,j]) Yd;
Exprxy:=Exprxy flag Exd;
end;
end;
end;
Expr:=floattostr(A[1,1]) Expry Exprx Exprxy;//拟合后的曲面多项式
//显示拟合后的结果
Memo1.Lines.Append('最小二乘曲面拟合');
Memo1.Lines.Append('标准曲面多项式');
Memo1.Lines.Append('P(x,y):=A(1,1) A(1,2)(x-x0) .. A(2,1)(y-y0) A(2,2)(x-x0)*(y-y0) A(2,3)(x-x0)*(y-y0)^2 … A(Q 1,P 1)(x-x0)^Q*(y-y0)^P');
Memo1.Lines.Append('其中X平均值:x0=(x1 x2 … xN)/N=' floattostr(XX));
Memo1.Lines.Append('其中Y平均值:y0=(y1 y2 … yM)/M=' floattostr(YY));
Memo1.Lines.Append('拟合多项式表达式如下:');
Memo1.Lines.Append('F(x)=' Expr ';');
for i:=1 to P do
begin //Memo中字符串之间不能夹插变量,变量之间不能夹插字符串输出,用strtemp变通
for j:=1 to Q do
begin
strtemp:=inttostr(i) ',' inttostr(j) ']:' floattostr(A[i,j]);
Memo1.Lines.Append('拟合多项式系数A[' strtemp);
end;
end;
Memo1.Lines.Append('多项式总项数:' floattostr(P*Q));
Memo1.Lines.Append('多项式与数据点偏差平方和:' floattostr(DT1));
Memo1.Lines.Append('多项式与数据点偏差绝对值和:' floattostr(DT2));
Memo1.Lines.Append('多项式与数据点偏差绝对值最大值:' floattostr(DT3));
Memo1.Lines.Append('拟合函数式:f(x)=' func);
if B_DrawFunc=True then DrawMultiCurve(func,Color4);//画函数曲线
if B_DrawMult=True then DrawMultiCurve(Expr,Color3);//画多项式表达式曲线
end;
//3切比雪夫曲线拟合,N实验数据个数,P多项式最高次幂数(项数为P 1)
procedure TF_MultiLineRegress.CheBySheV(N,P:integer);
var i,j,v,II:integer;//N拟合数据个数,M拟合多项式项数
X,Y,A,IX,H:Array of Double; //8字节浮点变量
HA,HH,Y1,Y2,H1,H2,D,HM,IM,L:Double;
Xd,Exd,flag,Expr,strtemp:string;//最后写多项式表达式时的临时变量
Label L10,L20,L30;
begin
SetLength(X,N 1);
SetLength(Y,N 1);
SetLength(A,P 1);
SetLength(IX,4*P);
SetLength(H,4*P);
//从表中取拟合数据到变量
for i:=1 to N do
begin
X[i]:=strtofloat(StringGrid1.Cells[1,i]);
Y[i]:=strtofloat(StringGrid1.Cells[2,i]);
end;
//切比雪夫拟合
HA:=0;
IX[1]:=1;
IX[P 1]:=N;
L:=(N-1)/P;
j:=Round(L);
for i:=2 to P do
begin
IX[i]:=j 1;
j:=j Round(L);
end;
L10:
HH:=1;
for i:=1 to P 1 do
begin
A[i]:=Y[Round(IX[i])];
H[i]:=-HH;
HH:=-HH;
end;
for j:=1 to P do
begin
II:=P 1;
Y2:=A[II];
H2:=H[II];
for i:=j to P do
begin
D:=X[Round(IX[II])]-X[Round(IX[P 1-i])];
Y1:=A[P-i j];
H1:=H[P-i j];
A[II]:=(Y2-Y1)/D;
H[II]:=(H2-H1)/D;
II:=P-i j;
Y2:=Y1;
H2:=H1;
end;
end;
HH:=-A[P 1]/H[P 1];
for i:=1 to P 1 do A[i]:=A[i] H[i]*HH;
for j:=1 to P-1 do
begin
II:=P-j;
D:=X[Round(IX[II])];
Y2:=A[II];
for v:=P 1-j to P do
begin
Y1:=A[V];
A[II]:=Y2-D*Y1;
Y2:=Y1;
II:=v;
end;
end;
HM:=abs(HH);
if HM<=HA then
begin
A[P 1]:=-HM;
goto L30;
end;
A[P 1]:=HM;
HA:=HM;
IM:=IX[1];
H1:=HH;
j:=1;
for i:=1 to N do
begin
if i=IX[j] then
begin
if j<P 1 then j:=j 1;
end else
begin
H2:=A[P 1];
v:=P-1;
while v>=1 do
begin
H2:=H2*X[i] A[v];
v:=v-1;
end;
H2:=H2-Y[i];
if abs(H2)>HM then
begin
HM:=abs(H2);
H1:=H2;
IM:=i
end;
end;
end;
if IM=IX[1] then goto L30;
i:=1;
L20:
if IM>=IX[i] then
begin
i:=i 1;
if i<=P 1 then goto L20;
end;
if i>P 1 then i:=P 1;
if i=Round((i/2)*2) then H2:=HH else H2:=-HH;
if H1*H2>=0 then
begin
IX[i]:=P;
goto L10;
end;
if IM<IX[1] then
begin
j:=P;
while j>=1 do
begin
IX[j 1]:=IX[j];
j:=j-1;
end;
IX[1]:=IM;
goto L10;
end;
if IM>IX[P 1] then
begin
for j:=2 to P 1 do IX[j-1]:=IX[j];
IX[P 1]:=IM;
goto L10;
end;
IX[i-1]:=IM;
goto L10;
L30:
//绘拟合后的多项式表达式
Expr:=floattostr(A[1]);
Xd:='';
for i:=2 to P do
begin
if A[i]>0 then
begin
flag:=' ';
Xd:=Xd '*x';
Exd:=floattostr(A[i]) Xd;
Expr:=Expr flag Exd;
end else if A[i]<0 then
begin
flag:='';
Xd:=Xd '*x';
Exd:=floattostr(A[i]) Xd;
Expr:=Expr flag Exd;
end;
end;
//显示多项式信息
Memo1.Lines.Append('切比雪夫曲线拟合');
Memo1.Lines.Append('标准曲面多项式');
Memo1.Lines.Append('多项式:P(x)=A[1] A[2]x A[3]x^2 … A[N]x^P …');
Memo1.Lines.Append('拟合多项式表达式如下:');
Memo1.Lines.Append('F(x)=' Expr);
for i:=1 to P do
begin //Memo中字符串之间不能夹插变量,变量之间不能夹插字符串输出,用strtemp变通
strtemp:=inttostr(i) ']:' floattostr(A[i]);
Memo1.Lines.Append('拟合多项式系数A[' strtemp);
end;
Memo1.Lines.Append('拟合多项式与数据点最大偏差Hmax:' floattostr(A[P 1]));
Memo1.Lines.Append('拟合函数式:f(x)=arctg(x)');
//将Expr表达式绘出曲线并与函数f(x)曲线比较
if B_DrawFunc=True then DrawMultiCurve(func,Color4);//画函数曲线
if B_DrawMult=True then DrawMultiCurve(Expr,Color3);//画多项式表达式曲线
end;
//4最佳一致逼近,N是多项式项数,A,B是取值区间,Precision是精度
procedure TF_MultiLineRegress.Remez(N:integer;A,B:Double);
var P:Array of Double;
X1,G:Array[1..20]of Double;
H,U,D,XX,X0,S,T,YY:Double;
i,j,v:integer;
Expression:TExpress;//函数表达式类
x:Double;//函数自变量
Xd,Exd,flag,Expr,strtemp:string;//最后写多项式表达式时的临时变量
Label L10,L20,L30,L40;
begin
Expression:=TExpress.Create(self);//创建字符串转换成表达式类
Expression.Expression:=func;//将字符串给表达式类
SetLength(P,N 1);
D:=1E 35;
for v:=0 to N do //求区间[A,B]上取N次切比雪夫多项式的交错点组
begin
T:=cos((N-v)*pi/N);
X1[v 1]:=(B A (B-A)*T)/2;
end;
L40:
U:=1;
for i:=1 to N 1 do
begin
x:=X1[i];
P[i]:=Expression.TheFunction(x,0,0);
G[i]:=-U;
U:=-U;
end;
for j:=1 to N do
begin
v:=N 1;
S:=P[v];
XX:=G[v];
for i:=j to N do
begin
T:=P[N-i j];
X0:=G[N-i j];
P[v]:=(S-T)/(X1[v]-X1[N 1-i]);
G[v]:=(XX-X0)/(X1[v]-X1[N 1-i]);
v:=N-i j;
S:=T;
XX:=X0;
end;
end;
U:=-P[N 1]/G[N 1];
for i:=1 to N 1 do P[i]:=P[i] G[i]*U;
for j:=1 to N-1 do
begin
v:=N-j;
H:=X1[v];
S:=P[v];
for i:=N 1-j to N do
begin
T:=P[i];
P[v]:=S-H*T;
S:=T;
v:=i;
end;
end;
P[N 1]:=abs(U);
U:=P[N 1];
if abs(U-D)<=Precision then goto L10;
D:=U;
H:=0.1*(B-A)/N;
XX:=A;
X0:=A;
L20:
if X0<=B then
begin
x:=X0;
S:=Expression.TheFunction(x,0,0);
T:=P[N];
i:=N-1;
while i>=1 do
begin
T:=T*X0 P[i];
i:=i-1;
end;
S:=abs(S-T);
if S>U then
begin
U:=S;
XX:=X0;
end;
X0:=X0 H;
goto L20;
end;
x:=XX;
S:=Expression.TheFunction(x,0,0);
T:=P[N];
i:=N-1;
while i>=1 do
begin
T:=T*XX P[i];
i:=i-1;
end;
YY:=S-T;
i:=1;
j:=N 1;
L30:
if j-i=1 then
begin
v:=Round((i j)/2);
if XX<X1[v] then j:=v else i:=v;
goto L30;
end;
if XX<X1[1] then
begin
x:=X1[1];
S:=Expression.TheFunction(x,0,0);
T:=P[N];
v:=N-1;
while v>=1 do
begin
T:=T*X1[1] P[v];
v:=v-1;
end;
S:=S-T;
if S*YY>0 then
begin
X1[1]:=XX;
end else
begin
v:=N;
while v>=1 do
begin
X1[v 1]:=X1[v];
v:=v-1;
end;
X1[1]:=XX;
end;
end else if XX>X1[N 1] then
begin
x:=X1[N 1];
S:=Expression.TheFunction(x,0,0);
T:=P[N];
v:=N-1;
while v>=1 do
begin
T:=T*X1[N 1] P[v];
v:=v-1;
end;
S:=S-T;
if S*YY>0 then
begin
X1[N 1]:=XX
end else
begin
for v:=1 to N do X1[v]:=X1[v 1];
X1[N 1]:=XX;
end;
end else
begin
x:=X1[i];
S:=Expression.TheFunction(x,0,0);
T:=P[N];
v:=N-1;
while v>=1 do
begin
T:=T*X1[i] P[v];
v:=v-1;
end;
S:=S-T;
if S*YY>0 then X1[i]:=XX else X1[j]:=XX;
end;
goto L40;
Exit;
L10:
//绘拟合后的多项式表达式
Expr:=floattostr(P[1]);
Xd:='';
for i:=2 to N do
begin
if P[i]>0 then
begin
flag:=' ';
Xd:=Xd '*x';
Exd:=floattostr(P[i]) Xd;
Expr:=Expr flag Exd;
end else if P[i]<0 then
begin
flag:='';
Xd:=Xd '*x';
Exd:=floattostr(P[i]) Xd;
Expr:=Expr flag Exd;
end;
end;
//显示多项式信息
Memo1.Lines.Append('最佳一致逼近米兹方法');
Memo1.Lines.Append('逼近标准多项式:P(x)=A[1] A[2]x A[3]x^2 … A[N]x^P …;');
Memo1.Lines.Append('逼近参考函数(绿色曲线):f(x)=' func);
Memo1.Lines.Append('逼近多项式(红色曲线)如下所示:P(x)=' Expr);
for i:=1 to N do
begin
strtemp:=inttostr(i) ']=' floattostr(P[i]);
Memo1.Lines.Append('逼近多项式系数A[' strtemp); //Memo中不能在字符串中间夹变量输出
end;
Memo1.Lines.Append('多项式与函数偏差:' floattostr(P[N 1]));
//将Expr表达式绘出曲线并与函数f(x)曲线比较
if B_DrawFunc=True then DrawMultiCurve(func,Color4);//画函数曲线
if B_DrawMult=True then DrawMultiCurve(Expr,Color3);//画多项式表达式曲线
end;
//5一元线性回归分析
procedure TF_MultiLineRegress.OneLineRegress(StrGrd:TStringGrid);
var X,Y:Array of Double;
N,i:integer;
A,B,Q,S,P,UMAX,UMIN,U:Double;
XX,YY,DX,DXY:Double;
Expr:string;
begin
N:=StrGrd.RowCount-1;
SetLength(X,N 1);
SetLength(Y,N 1);
for i:=1 to N do
begin
X[i]:=strtofloat(StrGrd.Cells[1,i]);
Y[i]:=strtofloat(StrGrd.Cells[2,i]);
end;
//求平均值
XX:=0;YY:=0;
for i:=1 to N do
begin
XX:=XX X[i];
YY:=YY Y[i];
end;
XX:=XX/N;YY:=YY/N; //X,Y的平均值
DX:=0;DXY:=0;
for i:=1 to N do
begin
Q:=X[i]-XX;
DX:=DX Q*Q;
DXY:=DXY Q*(Y[i]-YY)
end;
A:=DXY/DX;
B:=YY-A*XX;
Q:=0;U:=0;P:=0;UMAX:=0;UMIN:=1E 30;
for i:=1 to N do
begin
S:=A*X[i] B;
Q:=Q (Y[i]-S)*(Y[i]-S);
P:=P (S-YY)*(S-YY);
DX:=abs(Y[i]-S);
if DX>UMAX then UMAX:=DX;
if DX<UMIN then UMIN:=DX;
U:=U DX/N;
end;
S:=sqrt(Q/N);
if B>0 then
Expr:=floattostr(A) '*x' ' ' floattostr(B)
else if B<0 then
Expr:=floattostr(A) '*x' floattostr(B);
//显示多项式信息
Memo1.Lines.Append('一元线性回归分析');
Memo1.Lines.Append('一元线性标准方式:y(x)=Ax B');
Memo1.Lines.Append('y(x)=' Expr ';');
Memo1.Lines.Append('线性方式的偏差平方和:' floattostr(Q));
Memo1.Lines.Append('线性方式平均标准偏差:' floattostr(S));
Memo1.Lines.Append('线性方式的回归平方和:' floattostr(P));
Memo1.Lines.Append('线性方式的最大偏差值:' floattostr(UMAX));
Memo1.Lines.Append('线性方式的最小偏差值:' floattostr(UMIN));
Memo1.Lines.Append('线性方式的平均偏差值:' floattostr(U));
//将Expr表达式绘出曲线并与函数f(x)曲线比较
if B_DrawMult=True then DrawMultiCurve(Expr,Color3);//画多项式表达式曲线
end;
//6多元线性回归
procedure TF_MultiLineRegress.MulLineRegress(StrGrd:TStringGrid);
var X,B:Array of Array of Double;
Y,A,V:Array of Double;
Q,S,R,U,YY,DYY,P,PP:Double;
N,M,i,j,t:integer;
flage,Expr,str1,str2,strtemp:string;
Label L10;
begin
M:=StrGrd.ColCount-2; //自变量个数,减去序号和因变量列
N:=StrGrd.RowCount-1; //实验数据组的组数
SetLength(X,M,N); //存放自变量M*N个观测值
SetLength(B,M 1,M 1);
SetLength(Y,N); //存放因变量N个观测值
SetLength(A,M 1); //存放M 1个回归系统数a1,a2..
SetLength(V,M); //M个自变量的偏相关系数
if M=2 then flage:='二' else if M=3 then flage:='三'
else if M=4 then flage:='四' else if M>=5 then flage:='多';
//给测试数据变量组,Y[i],X[j,i]赋值
for i:=0 to N-1 do Y[i]:=strtofloat(StrGrd.Cells[1,i 1]);
for j:=0 to M-1 do
for i:= 0 to N-1 do
X[j,i]:=strtofloat(StrGrd.Cells[j 2,i 1]);
B[0,0]:=N;
for j:=1 to M do
begin
B[0,j]:=0;
for i:=0 to N-1 do B[0,j]:=B[0,j] X[j-1,i];
B[j,0]:=B[0,j];
end;
for i:=1 to M do
begin
for j:=i to M do
begin
B[i,j]:=0;
for t:=0 to N-1 do B[i,j]:=B[i,j] X[i-1,t]*X[j-1,t];
B[j,i]:=B[i,j];
end;
end;
A[0]:=0;
for i:=0 to N-1 do A[0]:=A[0] Y[i];
for i:=1 to M do
begin
A[i]:=0;
for j:=0 to N-1 do A[i]:=A[i] X[i-1,j]*Y[j];
end;
//乔里斯基分解求对称正定方程组
if B[0,0]=0 then goto L10;
B[0,0]:=sqrt(B[0,0]);
for j:=1 to M do B[0,j]:=B[0,j]/B[0,0];
for i:=1 to M do
begin
for j:=1 to i do B[i,i]:=B[i,i]-B[j-1,i]*B[j-1,i];
if B[i,i]=0 then goto L10;
B[i,i]:=sqrt(B[i,i]);
if i<>M then
begin
for j:=i 1 to M do
begin
for t:=1 to i do B[i,j]:=B[i,j]-B[t-1,i]*B[t-1,j];
B[i,j]:=B[i,j]/B[i,i];
end;
end;
end;
A[0]:=A[0]/B[0,0];
for i:=1 to M do
begin
for t:=1 to i do A[i]:=A[i]-B[t-1,i]*A[t-1];
A[i]:=A[i]/B[i,i];
end;
A[M]:=A[M]/B[M,M];
t:=M;
while t>=1 do
begin
for i:=t to M do A[t-1]:=A[t-1]-B[t-1,i]*A[i];
A[t-1]:=A[t-1]/B[t-1,t-1];
t:=t-1;
end;
L10:
//乔里斯基分解求结束
YY:=0;
for i:=0 to N-1 do YY:=YY Y[i]/N;
Q:=0;
DYY:=0;
U:=0;
for i:=0 to N-1 do
begin
P:=A[0];
for j:=0 to M-1 do P:=P A[j 1]*X[j,i];
Q:=Q (Y[i]-P)*(Y[i]-P);
DYY:=DYY (Y[i]-YY)*(Y[i]-YY);
U:=U (YY-P)*(YY-P);
end;
S:=sqrt(Q/N);
R:=sqrt(1-Q/DYY);
for j:=0 to M-1 do
begin
P:=0;
for i:=0 to N-1 do
begin
PP:=A[0];
for t:=0 to M-1 do if t=j then PP:=PP A[t 1]*X[t,i];
P:=P (Y[i]-PP)*(Y[i]-PP);
end;
V[j]:=sqrt(1-Q/P);
end;
//显示多元线性方程信息
Expr:=floattostr(A[0]);
for i:=0 to M-1 do
begin
if A[i 1]>0 then
Expr:=Expr ' ' floattostr(A[i 1]) '*x' inttostr(i 1)
else if A[i 1]<0 then
Expr:=Expr floattostr(A[i 1]) '*x' inttostr(i 1);
end;
Expr:=Expr ';';
Memo1.Lines.Append(flage '元线性回归分析');
Memo1.Lines.Append(flage '元线性标准方程:y(x1,x2..xM)=A1 A2*x1 A3*x2 .. A(M 1)*xM');
Memo1.Lines.Append('Y=' Expr);
Memo1.Lines.Append(flage '元线性方程各系数值如下所示:');
for i:=0 to M do
begin
strtemp:=floattostr(i 1) ')=' floattostr(A[i]);
Memo1.Lines.Append('A(' strtemp); //Memo字符串中间不能夹插变量
end;
Memo1.Lines.Append('方程的偏差平方和Q:' floattostr(Q));
Memo1.Lines.Append('方程平均标准偏差S:' floattostr(S));
Memo1.Lines.Append('方程的复相关系数R:' floattostr(R));
Memo1.Lines.Append('方程偏差系数如下所示:');
for i:=0 to M-1 do
begin
strtemp:=floattostr(i 1) ')=' floattostr(V[i]);
Memo1.Lines.Append('V(' strtemp);
end;
Memo1.Lines.Append('方程的回归平方和U:' floattostr(U));
Memo1.Lines.Append(flage '元线性回归后的分析信息如下:');
if R>0.9 then Memo1.Lines.Append('线性回归效果很好!')
else if R<0.8 then Memo1.Lines.Append('线性回归效果不理想!');
for i:=0 to M-1 do
begin
if V[i]>0.9 then Memo1.Lines.Append('自变量X' inttostr(i 1) '对Y的作用较强,不可剔除!');
end;
//将Expr表达式绘出曲线并与函数f(x)曲线比较
if(B_DrawMult=True)and(AnalysSel='f')then
begin
if A[1]>0 then str1:=' ' else if A[1]<0 then str1:='';
if A[2]>0 then str2:=' ' else if A[2]<0 then str2:='';
if(A[1]=0)or(A[2]=0)then
begin
Expr:=floattostr(A[0]) str1 floattostr(A[1]) '*x' str2 floattostr(A[2]) '*y';
DrawMultiCurve(Expr,Color3);//画多项式表达式曲线
end;
end;
end;
//7逐步回归(针对多元线性回归)
procedure TF_MultiLineRegress.StepRegress(StrGrd:TStringGrid;F1,F2,E:Double);
var N,M :integer;//自变量个数,观测点数
//F1是欲选入因子时显著性检验F-分布值,F2是欲剔除因子时显著性检验F-分布值,E是防止系数相关阵退化的判据
L,i,j,t:integer;
X:Array of Array of Double;//M个观测点上的数据组,前N个为自变量用,最后一个是因变量用
R:Array of Array of Double;//存放最终规格化的系数相关阵
XX:Array of Double;//前N个存放自变量因子的算术平均值
B:Array of Double;//前N个存放各因子的回归系数b1,b2..
V:Array of Double;//前N个存放各因子的偏回归平方和,最后一个存放残差平方和Q
S:Array of Double;//前N个存放各因子回归系数的标准偏差,最后一个存放估计标准偏差
YE:Array of Double;
YR:Array of Double;
C,F,Z,Q:Double;
FMI,FMX,PHI,VMI,VMX,SD:Double;
IMI,IMX:integer;
Label L10,L20;
begin
//置输入值
N:=StrGrd.ColCount-1; //变量个数,减去序号列
M:=StrGrd.RowCount-1; //实验数据组的组数(观测点数),减去标题行
//为动态数组设置内存空间
SetLength(X,M,N);
SetLength(R,M,N);
SetLength(XX,N);
SetLength(B,N);
SetLength(V,N);
SetLength(S,N);
SetLength(YE,M);
SetLength(YR,M);
//自变量赋值
for i:=0 to M-1 do //观测数据组数(记录数)
begin
for j:=0 to N-2 do//自变量个数(字段数)
begin
X[j,i]:=strtofloat(StrGrd.Cells[j 2,i 1]);
end;
end;
//因变量赋值
for i:=0 to M-1 do //观测数据组数
X[N-1,i]:=strtofloat(StrGrd.Cells[1,i 1]);
//开始执行回归
for j:=0 to N-1 do
begin
Z:=0;
for i:=0 to M-1 do Z:=Z X[i,j]/M;
XX[j]:=Z; //求变量平均值
end;
for i:=0 to N-1 do
begin
for j:=0 to i do
begin
Z:=0;
for t:=0 to M-1 do Z:=Z (X[t,i]-XX[i])*(X[t,j]-XX[j]);
R[i,j]:=Z; //还系数相关值
end;
end;
C:=0;F:=0;Q:=0;
for i:=0 to N-1 do YE[i]:=sqrt(R[i,i]);
for i:=0 to N-1 do
begin
for j:=0 to i do
begin
R[i,j]:=R[i,j]/(YE[i]*YE[j]);
R[j,i]:=R[i,j];
end;
end;
PHI:=M-1;
SD:=YE[N-1]/sqrt(M-1);
L10:
VMI:=1E 35;
VMX:=0;
IMI:=0;
IMX:=0;
for i:=0 to N-1 do
begin
V[i]:=0;
B[i]:=0;
S[i]:=0;
end;
i:=0;
L20:
i:=i 1;
if R[i,i]>=E then
begin
V[i]:=R[i,N-1]*R[N-1,i]/R[i,i];
if V[i]>=0 then
begin
if V[i]>VMX then
begin
VMX:=V[i];
IMX:=i;
end;
end else
begin
B[i]:=R[i,N-1]*YE[N-1]/YE[i];
S[i]:=sqrt(R[i,i])*SD/YE[i];
if abs(V[i])<VMI then
begin
VMI:=abs(V[i]);
IMI:=i;
end;
end;
end;
if i<>N-2 then goto L20;
if PHI<>N-3 then
begin
Z:=0;
for i:=0 to N-2 do Z:=Z B[i]*XX[i];
B[N-1]:=XX[N-1]-Z;
S[N-1]:=SD;
V[N-1]:=Q;
end else
begin
B[N-1]:=XX[N-1];
S[N-1]:=SD;
end;
FMI:=VMI*PHI/R[N-1,N-1];
FMX:=(PHI-1)*VMX/(R[N-1,N-1]-VMX);
if(FMI<F2)or(FMX>=F1)then
begin
if FMI<F2 then
begin
PHI:=PHI 1;
L:=IMI;
end else
begin
PHI:=PHI-1;
L:=IMX;
end;
for i:=0 to N-1 do
begin
if i<>L then
begin
for j:=0 to N-1 do
begin
if j<>L then R[i,j]:=R[i,j]-(R[L,j]/R[L,L])*R[i,L];
end;
end;
end;
for j:=0 to N-1 do
begin
if j<>L then R[L,j]:=R[L,j]/R[L,L];
end;
for i:=0 to N-1 do
begin
if I<>L then R[i,L]:=-R[i,L]/R[L,L];
end;
R[L,L]:=1/R[L,L];
Q:=R[N-1,N-1]*YE[N-1]*YE[N-1];
SD:=sqrt(R[N-1,N-1]/PHI)*YE[N-1];
C:=sqrt(1-R[N-1,N-1]);
F:=(PHI*(1-R[N-1,N-1]))/((M-PHI-1)*R[N-1,N-1]);
goto L10;
end;
for i:=0 to M-1 do
begin
Z:=0;
for j:=0 to N-2 do Z:=Z B[j]*X[i,j];
YE[i]:=B[N-1] Z;
YR[i]:=X[i,N-1]-YE[i];
end;
//显示多项式信息
Memo1.Lines.Append('逐步回归分析');
Memo1.Lines.Append('逐步回归多元线性估计标准方程式如下:');
Memo1.Lines.Append('y=B0 B1x1 B2x2 .. BNxN;');
Memo1.Lines.Append('回归系数:B0=' floattostr(B[N-1]) ';');
for i:=0 to N-2 do
Memo1.Lines.Append('回归系数:B' inttostr(i 1) '=' floattostr(B[i]) ';');
Memo1.Lines.Append('因变量算术平均值:Y =' floattostr(XX[N-1]) ';');
for i:=0 to N-2 do //N变量个数,M记录条数
Memo1.Lines.Append('自变量算术平均值:X' inttostr(i 1) '=' floattostr(XX[i]) ';');
Memo1.Lines.Append('回归残存平方和:Q=' floattostr(V[N-1]) ';');
for i:=0 to N-2 do
Memo1.Lines.Append('偏回归平方和:V[' inttostr(i 1) ']=' floattostr(V[i]) ';');
Memo1.Lines.Append('估计标准偏差:S[0]=' floattostr(S[N-1]) ';');
for i:=0 to N-2 do
Memo1.Lines.Append('回归系数标准偏差:S[' inttostr(i 1) ']=' floattostr(S[i]) ';');
Memo1.Lines.Append('复相关系数:C=' floattostr(C) ';');
Memo1.Lines.Append('F-检测值:' floattostr(F) ';');
for i:=0 to M-1 do
Memo1.Lines.Append('因变量条件期望估计值:YE[' inttostr(i 1) ']=' floattostr(YE[i]) ';');
for i:=0 to M-1 do
Memo1.Lines.Append('因变量观测值的残差:YR[' inttostr(i 1) ']=' floattostr(YR[i]) ';');
for i:=0 to N-1 do
begin
for j:=0 to N-1 do
begin
Memo1.Lines.Append('系统相关阵:R[' inttostr(i 1) ',' inttostr(j 1) ']=' floattostr(R[i,j]) ';');
end;
end;
Memo1.Lines.Append('运算完毕!');
end;
//8五点三次平滑 (只能用动态数组类设置数组)
procedure TF_MultiLineRegress.FiveThreeSmooth(StrGrd:TStringGrid;ColRead,ColWrite:integer);
var N,i:integer;//Y放实验数据,YY放平滑数据
Y,YY:Array of Double;
begin
N:=StrGrd.RowCount-1;
SetLength(Y,N 1);
SetLength(YY,N 1);
for i:=1 to N do Y[i]:=strtofloat(StrGrd.Cells[ColRead,i]);
if N<5 then for i:=1 to N do YY[i]:=Y[i];
YY[1]:=(69*Y[1] 4*Y[2]-6*Y[3] 4*Y[4]-Y[5])/70;
YY[2]:=(2*Y[1] 27*Y[2] 12*Y[3]-8*Y[4] 2*Y[5])/35;
for i:=3 to N-2 do YY[i]:=(-3*Y[i-2] 12*Y[i-1] 17*Y[i] 12*Y[i 1]-3*Y[i 2])/35;
YY[N-1]:=(2*Y[N-4]-8*Y[N-3] 12*Y[N-2] 27*Y[N-1]-2*Y[N])/35;
YY[N]:=(-Y[N-4] 4*Y[N-3]-6*Y[N-2] 4*Y[N-1] 69*Y[N])/70;
StrGrd.ColCount:=StrGrd.ColCount 1;
for i:=1 to StrGrd.ColCount-1 do StrGrd.ColWidths[i]:=
(StrGrd.Width-StrGrd.ColWidths[0])div (StrGrd.ColCount-1)-8;
StrGrd.Cells[ColRead,0]:='实验数据';
StrGrd.Cells[ColWrite,0]:='平滑数据';
for i:=1 to N do StrGrd.Cells[ColWrite,i]:=floattostr(YY[i]);
end;
//画五点三次平滑数据点的折线
procedure TF_MultiLineRegress.DrawFoldLine(StrGrd:TStringGrid;Col:integer;Color:TColor);
var x1world,y1world,z1world,x2world,y2world,z2world:Double;
Y:Array of Double;
XN_min,N,i:integer; //XX是这些数据两两之间的X轴平均距离
XX:Double;
begin
Image1.Canvas.Pen.Width:=Width3;//数据线宽度
Image1.Canvas.Pen.Color:=Color;//曲线颜色(这里是折线颜色)
Image1.Canvas.Pen.Style:=PSSolid;//坐标为实线
N:=StrGrd.RowCount-1;
SetLength(Y,N 1);
for i:=1 to N do Y[i]:=strtofloat(StrGrd.Cells[Col,i]);
//画" "字
XX:=(DrawX_max-DrawX_min)/(N-1);
x1world:=0;x2world:=0;y1world:=0;y2world:=0;z1world:=0;z2world:=0;
XN_min:=Trunc(abs(DrawX_min)/XX);//负X轴的XX个数
for i:= 0 to N-2 do
begin
x1world:=-(XN_min-i)*XX;
x2world:=-(XN_min-i-1)*XX;
z1world:=Y[i 1];
z2world:=Y[i 2];
DrawCrossLine(x1world,y1world,z1world,Color);//画' '字
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//画折线
end;
DrawCrossLine(x2world,y2world,z2world,Color);//画' '字
end;
//输出结果按钮
procedure TF_MultiLineRegress.SpeedButton4Click(Sender: TObject);
var mr:integer;
begin
mr:=Application.MessageBox('您真的想打印相关结果吗?' #13
'' #13
'注意:按“是”打印显示曲线,' #13
' 按“否”打印分析结果,' #13
' 按“取消”放弃打印!','输出结果说明',
$30 $3); //MB_IconInformation MB_YesNoCancel
if mr=mrYes then
PrintConic //打印曲线
else if mr=mrNo then
PrintMemoData(Memo1)//打印结果
else if mr=mrCancel then //放弃保存
Exit;
end;
//注册帮助按钮
procedure TF_MultiLineRegress.SpeedButton5Click(Sender: TObject);
begin
Panel6.Visible:=True; //通过注册窗口显示帮助
Edit1.Text:=MachineCode0; //调用CPUID号
Label7.Caption:=
' 您觉得这个小软件对您有用吗?您觉' #13
'得这个小软件的功能适合您的需要吗?您' #13
'想拥有这个小软件的完全使用权吗?敬请' #13
'您注册吧!' #13
' 注册很简单,只需要获得注册码,并' #13
'将注册码输入到这个系统中,您就获得了' #13
'这个《拟合平滑回归分析》的注册权,您' #13
'就能享受这个系统的所有功能!' #13
' 想要得到注册码,您只需要将窗口中' #13
'显示的机器码字符,电子邮件给作者,您' #13
'就可以获得作者邮寄给您的该软件的有效' #13
'注册码,同时还能享受作者定期给系统的' #13
'免费升级服务,享受作者无偿的技术支持' #13
'。前提当然只有一个,在邮寄机器码时不' #13
'要忘记给作者寄上壹佰元人民币厚礼。作' #13
'者将真诚地感谢您对正版软件的支持!' #13
' 得到注册码后,直接将注册码输入到' #13
'下面的“ 输入注册码 ” 窗口中,然后点下' #13
'面的“注册”按钮,系统显示“注册成功”后' #13
',您就可以完全使用该系统了。' #13
' 作者的通信地址如下:' #13
' 地址:湖南省岳阳移动通信分公司' #13
' 姓名:张长青' #13
' 邮编:414000' #13
' 电话:13707309869' #13
' Email:13707309869@139.com';
Timer1.Enabled:=True; //激活窗口显示
Button7.SetFocus;
end;
//打印显示曲线过程
procedure TF_MultiLineRegress.PrintConic;
var Rect:TRect;
begin
if drawK=True then
begin
Rect.Left:=20*Trunc(GetDeviceCaps(Printer.Handle,LOGPIXELSX)/96);
Rect.Top:=20*Trunc(GetDeviceCaps(Printer.Handle,LOGPIXELSX)/96);
try
if PrintDialog1.Execute then //打印对话框是否打开
begin
with Printer do
begin
begindoc; //创建打印文档
Printer.Canvas.StretchDraw(Rect,Image1.Picture.Graphic);
enddoc; //送往打印机
end;
ShowMessage('已完成显示曲线打印!');
end else begin
ShowMessage('图形没有打印!');
end;
except
ShowMessage('该图形文件不能打印!');
end;
end else begin
ShowMessage('没有图形文件可以打印!');
end;
end;
//打印分析结果过程
procedure TF_MultiLineRegress.PrintMemoData(Memo:TMemo);
var i:integer; //须在Uses中加入Printers函数
PrintText:System.Text;
begin
if Memo.Text<>'' then
begin
try
if PrintDialog1.Execute then //打印对话框是否打开
begin
AssignPrn(PrintText); //将打印文件PrintText与打印机关联
ReWrite(PrintText); //调节器用ReWrite函数作为输出打开分配的文件
with Printer do
begin
//begindoc; //创建打印文档
Canvas.Font.Size:=16; //赋与打印对象Canves的字体属性
Canvas.Font.Style:=[fsBold];
Canvas.Font.Name:='华文仿宋';
Canvas.Font.Color:=clDefault;
for i := 0 to Memo1.Lines.Count – 1 do
WriteLn(PrintText,Memo1.Lines.Strings[i]);//所存储在Memo2中的抽奖名单写到打印对象上
//enddoc; //送往打印机
System.Close(PrintText); //关闭打印文件
end;
ShowMessage('已完成显示结果打印!');
end else begin
ShowMessage('数据结果没有打印!');
end;
except
ShowMessage('该数据结果不能打印!');
end;
end else begin
ShowMessage('没有数据结果可以打印!');
end;
end;
//锁定表格
procedure TF_MultiLineRegress.Button1Click(Sender: TObject);
begin
if Button1.Caption='锁定表格只读' then
begin
Button1.Caption:='解锁表格可写';
Label1.Caption:='注意:目前表格不可写!';
StringGrid1.Options:=StringGrid1.Options-[goEditing];//StringGrid1表格单元只读
end else if Button1.Caption='解锁表格可写' then
begin
Button1.Caption:='锁定表格只读';
Label1.Caption:='注意:目前表格可写!';
StringGrid1.Options:=StringGrid1.Options [goEditing];//StringGrid1表格单元可写
end;
end;
//文件调入数据按钮
procedure TF_MultiLineRegress.Button2Click(Sender: TObject);
begin
OpenChildForm(TF_FileDataInput,F_FileDataInput,self);
end;
//注册帮助按钮–程序使用帮助
procedure TF_MultiLineRegress.Button3Click(Sender: TObject);
var helpname:string; //帮助文件的完全路径
begin
helpname:=ExtractFilePath(paramstr(0)) 'helpchm.chm';//指出帮助文件完全路径
if not FileExists(helpname) then //若初始化文件不存在,则重建该文件
ShowMessage('帮助文件不存在,系统不能打开!')
else
ShellExecute(Handle,'open',PChar(helpname),nil,nil,SW_SHOW);
Timer1.Enabled:=False;
Panel6.Visible:=False;
end;
//删除StringGrid中的数据按扭
procedure TF_MultiLineRegress.Button4Click(Sender: TObject);
var str1,str2:string;
begin
str1:='您真的想删除第' inttostr(StringGrid1.Row) '条记录吗?';
str2:='系统提示';
if Application.MessageBox(PAnsiChar(str1),PAnsiChar(str2),
MB_IconInformation MB_YesNo)=mrYes then
StrGrdDeleteRow(StringGrid1);
end;
//插入StringGrid中的数据按扭
procedure TF_MultiLineRegress.Button5Click(Sender: TObject);
var str1,str2:string;
begin
str1:='您真的想在第' inttostr(StringGrid1.Row) '行处插入记录吗?';
str2:='系统提示';
if Application.MessageBox(PAnsiChar(str1),PAnsiChar(str2),
MB_IconInformation MB_YesNo)=mrYes then
StrGrdInsertRow(StringGrid1);
end;
//保存StringGrid中的数据按扭
procedure TF_MultiLineRegress.Button6Click(Sender: TObject);
var mr:integer;
begin
if StringGrid1.Cells[1,1]<>'' then
begin
mr:=Application.MessageBox('您真的想保存该数据吗?' #13
'' #13
'说明:按“是”保存为文本,' #13
' 按“否”保存为EXCEL,' #13
' 按“取消”放弃保存!','系统提示',
MB_IconInformation MB_YesNoCancel);
if mr=mrYes then //保存为文本
begin
StrGrdToText(StringGrid1,'实验数据资料');
ShowMessage('已完成文本数据保存!');
end else if mr=mrNo then //StringGrid转换成Excel表显示
begin
StrGrdToExcel(StringGrid1,'实验数据资料');
end else if mr=mrCancel then //放弃保存
begin
Exit;
end;
end else
begin
ShowMessage('表格中没有数据,不需要保存!');
end;
end;
//注册帮助按钮–注册
procedure TF_MultiLineRegress.Button7Click(Sender: TObject);
var Reg:TRegistry;
KeyName:string;
begin
if NoRegistry=False then
begin
ShowMessage('系统已注册,谢谢您!');
end else if Edit2.Text='' then
begin
ShowMessage('注册码不能为空,请重新输入!');
Edit2.SetFocus;
Exit;
end else
begin
LoginCode:=Edit2.Text; //将用户写的加密注册码给变量
if LoginCode=MachineCode1 then //判断加密注册码与登录时的机器加密码
begin
Reg:=TRegistry.Create; //创建注册表实例
Reg.RootKey:=HKEY_LOCAL_MACHINE; //建立根键
KeyName:='SoftWareP_MultiLineRegress'; //指定主键
if Reg.OpenKey(KeyName,False) then //打开关键词目录,若关键名不存在则创建
Reg.WriteString('LoginCode',LoginCode);//将用户注册码写入注册表
NoRegistry:=False; //打开注册开关
Reg.CloseKey; //关闭注册表各键
Reg.Free; //释放注册表内存
F_MultiLineRegress.Caption:='【拟合平滑回归分析】 ——注册版,谢谢您对正版软件的支持!';
ShowMessage('注册成功,谢谢您的支持!');
end else begin
ShowMessage('注册码不对,请重新输入');
if err_num>2 then
begin
NoRegistry:=True; //没有注册
ShowMessage('注册超过三次,注册不成功,退出!');
end else begin
Edit2.Text:='';
Edit2.SetFocus;
err_num:=err_num 1;
end;
end;
end;
Timer1.Enabled:=False;
Panel6.Visible:=False;
end;
//注册帮助按钮–退出
procedure TF_MultiLineRegress.Button8Click(Sender: TObject);
begin
Timer1.Enabled:=False;
Panel6.Visible:=False;
end;
//在StringGrid表格中删除行
procedure TF_MultiLineRegress.StrGrdDeleteRow(StrGrd:TStringGrid);
var i,j:integer;
begin
if StrGrd.Row>0then //StrGrd.Row是当前所指的行数
begin
with StrGrd do
begin
for i:=StrGrd.Row to RowCount-1 do
for j:=0 to ColCount-1 do cells[j,i]:=cells[j,i 1];
for j:=0 to ColCount-1 do cells[j,RowCount]:='';
RowCount:=RowCount-1;
end;
//在删除处重新排序号
for i:=StrGrd.Row to StrGrd.RowCount-1 do
StrGrd.Cells[0,i]:=inttostr(i);
end else
begin
ShowMessage('没有选择要删除行的位置!');
end;
end;
//在StringGrid表格中插入行
procedure TF_MultiLineRegress.StrGrdInsertRow(StrGrd:TStringGrid);
var i,j:integer;
begin
if StrGrd.Row>0then //StrGrd.Row是当前所指的行数
begin
with StrGrd do
begin
RowCount:=RowCount 1;
for i:=RowCount-1 downto StrGrd.Row do
for j:=1 to ColCount do cells[j,i]:=cells[j,i-1];
for j:=1 to ColCount do cells[j,StrGrd.Row]:='';
end;
//在插入处增加序号
for i:=StrGrd.Row to StrGrd.RowCount-1 do
StrGrd.Cells[0,i]:=inttostr(i);
end else
begin
ShowMessage('没有选择要插入行的位置!');
end;
end;
//StringGrid保存为文本
procedure TF_MultiLineRegress.StrGrdToText( //StringGrid保存为文本
StrGrd:TStringGrid; //转换成文本的StringGrid表格
DocmName:Shortstring); //转换成文本的表头标题名
var i,j:integer;
Str:string;
StrList:TStringList;
begin
SaveDialog1.Filter:='文本文件(*.txt)|*.txt'; //过滤文件类型
SaveDialog1.Title:='保存扫描资料结果!'; //窗口标题
SaveDialog1.DefaultExt:='.txt'; //保存文件默认扩展名
SaveDialog1.FileName:='实验数据资料'; //保存文件默认文件名
StrList:=TStringList.Create;
if SaveDialog1.Execute then
begin
for i:=0 to StrGrd.RowCount-1 do
begin
for j:=0 to StrGrd.ColCount-2 do
begin
Str:=Str StrGrd.Cells[j,i] ' '
end;
Str:=Str StrGrd.Cells[StrGrd.ColCount-1,i];
StrList.Append(Str);
Str:='';
end;
StrList.SaveToFile(SaveDialog1.FileName);
end;
StrList.Destroy;
end;
//注册窗口中的上下滚动广告
procedure TF_MultiLineRegress.Timer1Timer(Sender: TObject);
begin
Label7.Width:=220;
Label7.Top:=Label7.Top-1;
Label7.Left:=4;
if (Label7.Top<-Label7.Height 1) then
Label7.Top:=Panel7.Height-1;
end;
//StringGrid转换成Excel表显示(保存为EXCEL)
procedure TF_MultiLineRegress.StrGrdToExcel( //StringGrid转换成Excel表显示
StrGrd:TStringGrid; //转换成Excel的StringGrid表格
DocmName:Shortstring); //转换成Excel表的标题名
var i,j,k:integer;
ExcelApp,Range:Variant;
strCol,strRange_min,strRange_max:ShortString; //列,行数表示字母
const xlWBatWorkSheet=-4167;
begin
if StrGrd.Cells[1,1]='' then
begin
MessageBox(64,'表格没有数据转换!','警告信息框',MB_OK MB_ICONWARNING);
Exit;
end;
try
try
k:=0;
ProgressBar1.Min:=0;
ProgressBar1.Max:=StrGrd.ColCount*StrGrd.RowCount;
ProgressBar1.Position:=0;
ExcelApp:=CreateOLEObject('Excel.Application');//需要ComObj单元创建Excel对象)
ExcelApp.Caption:=DocmName;//更改Excel标题栏
ExcelApp.WorkBooks.Add(xlWBatWorkSheet);//添加新工作簿单工作表
for i := 0 to StrGrd.ColCount – 1 do
begin
for j := 0 to StrGrd.RowCount – 1 do
begin
ExcelApp.Goto('R' IntToStr(j 1) 'C' IntToStr(i 1));//Excel的表格是从1开始编号
ExcelApp.ActiveCell.FormulaR1C1:=StrGrd.Cells[i,j];//将StringGrid各单元字符串给EXCEL各单元
k:=k 1;
ProgressBar1.Position:=k;
end;
end;
if StrGrd.ColCount=1 then strCol:='A'
else if StrGrd.ColCount=2 then strCol:='B'
else if StrGrd.ColCount=3 then strCol:='C'
else if StrGrd.ColCount=4 then strCol:='D'
else if StrGrd.ColCount=5 then strCol:='E'
else if StrGrd.ColCount=6 then strCol:='F'
else if StrGrd.ColCount=7 then strCol:='G'
else if StrGrd.ColCount=8 then strCol:='H'
else if StrGrd.ColCount=9 then strCol:='I'
else if StrGrd.ColCount=10 then strCol:='J'
else if StrGrd.ColCount=11 then strCol:='K'
else if StrGrd.ColCount=12 then strCol:='L'
else if StrGrd.ColCount=13 then strCol:='M'
else if StrGrd.ColCount=14 then strCol:='N'
else if StrGrd.ColCount=15 then strCol:='O'
else if StrGrd.ColCount=16 then strCol:='P'
else if StrGrd.ColCount=17 then strCol:='Q'
else if StrGrd.ColCount=18 then strCol:='R'
else if StrGrd.ColCount=19 then strCol:='S'
else if StrGrd.ColCount=20 then strCol:='T'
else if StrGrd.ColCount=21 then strCol:='U'
else if StrGrd.ColCount=22 then strCol:='V'
else if StrGrd.ColCount=23 then strCol:='W'
else if StrGrd.ColCount=24 then strCol:='X'
else if StrGrd.ColCount=25 then strCol:='Y'
else if StrGrd.ColCount=26 then strCol:='Z';
//设置不同记录行字体属性:
strRange_min:='A' '1';
strRange_max:=strCol '1';
Range:=ExcelApp.ActiveSheet.Range[strRange_min ':' strRange_max];
Range.HorizontalAlignment:=xlCenter; // 文本水平居中方式(需要ExcelXP单元)
Range.Font.Color:=clRed; //字体颜色
Range.Font.name:='幼园'; //字体
Range.Font.Italic:=True; //斜体
Range.Interior.ColorIndex:=39; //填充颜色为淡紫色
//设置格式
ExcelApp.ActiveSheet.PageSetup.CenterHeader:=DocmName '的EXCEL表';//页眉
ExcelApp.ActiveSheet.PageSetup.CenterFooter:='第&P页';//页脚
ExcelApp.ActiveSheet.PageSetup.HeaderMargin:=1/0.035;//页眉到顶端边距1cm
ExcelApp.ActiveSheet.PageSetup.HeaderMargin:=1/0.035;//页脚到底端边距1cm
ExcelApp.ActiveSheet.PageSetup.TopMargin :=2/0.035;//顶边距2cm
ExcelApp.ActiveSheet.PageSetup.BottomMargin:=2/0.035;//底边距2cm
ExcelApp.ActiveSheet.PageSetup.LeftMargin:=1;//设置左页边距
ExcelApp.ActiveSheet.PageSetup.RightMargin:=1;//设置右页边距
ExcelApp.ActiveSheet.PageSetup.CenterHorizontally:=1/0.035;//页面水平居中
ExcelApp.ActiveSheet.PageSetup.CenterVertically:=1/0.035;//页面垂直居中
ExcelApp.ActiveSheet.PageSetup.Zoom:=100;//设置显示比例
ExcelApp.ActiveSheet.PageSetup.PaperSize:=xlPaperA4;//设置打印纸张(需要ExcelXP单元)
ExcelApp.ActiveSheet.PageSetup.PrintGridLines:=True;//打印单元格网线
Application.BringToFront; //程序前置
Cursor:=crSQLWait;
ShowMessage('数据库到Excel的数据传输完毕!');
ExcelApp.Visible:=True;//显示当前窗口
except
Application.MessageBox('因故不能打开Excel表!',PChar(Application.Title),MB_ICONERROR);
end;
finally
Cursor:=crDefault;
end;
end;
//文件调入数据子过程
procedure TF_MultiLineRegress.InputFileData;
var ExaName:shortstring; //调入文档扩展名
i:integer;
begin
OpenDialog1.Title:='请输入文本、EXCEL、ACCESS,SQL文件数据';
OpenDialog1.Filter:='TEXT,EXCEL,ACCESS,SQL(*.txt;*.xls;*.mdb;*.mdf)|*.txt;*.xls;*.mdb;*.mdf|';
if OpenDialog1.Execute then
begin
ExaName:=extractfileext(OpenDialog1.FileName);//取文件名扩展名
if (ExaName='.txt')or(ExaName='.TXT') then //文本表格
begin
StatusBar1.Panels[1].Text:='『调入文本表格数据』';
InputTextDocm(StringGrid1);
end else if (ExaName='.xls')or(ExaName='.XLS') then //EXECL表格
begin
InputExcelDocm(ADOTable1,SheetName,StringGrid1);
end else if (ExaName='.mdb')or(ExaName='.MDB') then //ACCESS表格
begin
StatusBar1.Panels[1].Text:='『调入ACCESS表数据』';
InputAccessDocm(ADOTable1,SheetName,StringGrid1);
end else if (ExaName='.mdf')or(ExaName='.MDF') then //SQL表格
begin
StatusBar1.Panels[1].Text:='『调入SQL表数据』';
InputSQLDocm(ADOTable1,SheetName,StringGrid1);
end;
for i:=1 to StringGrid1.RowCount-1 do
StringGrid1.Cells[0,i]:=inttostr(i);
Record_Num:=StringGrid1.RowCount-1;
StrGrdChang(StringGrid1); //StringGrid列变
end;
F_FileDataInput.Close; //关闭F_FileDataInput窗口
end;
//录入文本过程(将文本文件TXT转换成STRINGGRID数据表模式)
procedure TF_MultiLineRegress.InputTextDocm(StringGrid:TStringGrid);
var TxtSL:TStringlist;
i,j,k,u,w:integer;//i是记录数,j是字段数
TmpStr:string;//临时字符串记录变量
begin
TxtSL:=TStringlist.Create; //创建字符串列表类TxtSL
TxtSL.LoadFromFile(OpenDialog1.FileName); //将所选择文本数据表调入字符串列表类TxtSL
if TxtSL.Count>0 then //若字符串列表中有记录存在
begin
//为求表格列数和进程条最大值
w:=0;TmpStr:=TxtSL.Strings[0];
for j:=1 to ChEnCharLen(TmpStr) 1 do //每行字符串最后都有回车和换行两个字符
begin //ChEnCharLen该函数将中西文字符数分别计算
if(MidStr(TmpStr,j,1)=' ')or(j=ChEnCharLen(TmpStr) 1)then//测试j处字符是Tab或记录结束
begin
w:=w 1; //累加测试文本数据表的列数
end;
end;
StringGrid.ColCount:=w 1; //求总表格列数
StringGrid.RowCount:=TxtSL.Count 1;
//下面进行字段字符串的切分
for i:=0 to TxtSL.Count-1 do
begin
TmpStr:=TxtSL.Strings[i];
k:=0;u:=1;w:=1; //Length(TmpStr)该函数只将字符按本文方式计算
for j:=1 to ChEnCharLen(TmpStr) 1 do //每行字符串最后都有回车和换行两个字符
begin //ChEnCharLen该函数将中西文字符数分别计算
if(MidStr(TmpStr,j,1)=' ')or(j=ChEnCharLen(TmpStr) 1)then//测试j处字符是Tab或记录结束
begin
StringGrid.Cells[w,i 1]:=MidStr(TmpStr,u,k);//U取字符开始位置,k取字符个数
w:=w 1;
u:=j 1;
k:=0;
end else
begin
k:=k 1;
end;
end;
end;
end;
end;
//将StrGrd中的数据用' '号画出来
procedure TF_MultiLineRegress.DrawDataCross(StrGrd:TStringGrid);
var i:integer;
x,y,z:Double; //画 号临时变量
begin
if Variable_Num=2 then
begin
for i:=1 to StrGrd.RowCount-1 do
begin
StrGrd.Cells[0,i]:=inttostr(i); //对StringGrid中写序号
x:=strtofloatdef(StrGrd.Cells[1,i],0);
y:=0;
z:=strtofloatdef(StrGrd.Cells[2,i],0);
DrawCrossLine(x,y,z,Color4);//把实验数据点画为‘ ‘号
end;
end else if Variable_Num=3 then
begin
for i:=1 to StrGrd.RowCount-1 do
begin
StrGrd.Cells[0,i]:=inttostr(i); //对StringGrid中写序号
x:=strtofloatdef(StrGrd.Cells[1,i],0);
y:=strtofloatdef(StrGrd.Cells[2,i],0);
z:=strtofloatdef(StrGrd.Cells[3,i],0);
DrawCrossLine(x,y,z,Color4);//把实验数据点画为‘ ‘号
end;
end;
end;
//录入EXCEL表记录
procedure TF_MultiLineRegress.InputExcelDocm(ADOTable:TADOTable;
ExcelSheet:shortstring;StringGrid:TStringGrid);
var ACol,ARow:integer; //表格中的行,列
begin
ADOTable.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' OpenDialog1.FileName ';Extended Properties=Excel 8.0;Persist Security Info=False';
ADOTable.TableDirect:=True; //直接打开工作表,不作认证
ADOTable.TableName:=ExcelSheet; //打开EXCEL指定工作表ExcelSheet
ADOTable.Active:=True; //激活ADO表连接引擎
StringGrid.ColCount:=ADOTable.FieldCount 1;//列记录数,另加一列序号
StringGrid.RowCount:=ADOTable.RecordCount 1; //行记录数
ADOTable.First; //将表的指针指向记录第一
for ARow:=1 to ADOTable.RecordCount 1 do //记录数(行RecordCount)
begin
for ACol:=0 to ADOTable.FieldCount-1 do //字段数(列FieldCount)
StringGrid.Cells[ACol 1,ARow]:=ADOTable.Fields[ACol].AsString;
ADOTable.Next;
StringGrid.Cells[0,ARow]:=inttostr(ARow);
end;
ADOTable.Active:=False; //关闭ADO表连接引擎
end;
//录入ACCESS表记录
procedure TF_MultiLineRegress.InputAccessDocm(ADOTable:TADOTable;
AccessSheet:shortstring;StringGrid:TStringGrid);//录入ACCESS表记录
var ACol,ARow:integer; //表格中的行,列
begin
ADOTable.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' OpenDialog1.FileName ';Persist Security Info=False';
ADOTable.TableDirect:=True; //直接打开工作表,不作认证
ADOTable.TableName:=AccessSheet; //打开Access工作表
ADOTable.Active:=True; //激活ADO表连接引擎
StringGrid.ColCount:=ADOTable.FieldCount 1;//在StringGrid控件上画字段数(列)表格
StringGrid.RowCount:=ADOTable.RecordCount 1; //记录数(行)
for ARow := 1 to ADOTable.RecordCount 1 do //记录数(行RecordCount)
begin
for ACol := 0 to ADOTable.FieldCount-1 do //字段数(列FieldCount)
StringGrid.Cells[ACol,ARow]:=ADOTable.Fields[ACol].AsString;
ADOTable.Next;
end;
ADOTable.Active:=False; //关闭ADO表连接引擎
end;
//录入SQLServer表记录
procedure TF_MultiLineRegress.InputSQLDocm(ADOTable:TADOTable;
SQLSheet:shortstring;StringGrid:TStringGrid);//录入SQLServer表记录
var ACol,ARow:integer; //表格中的行,列
begin
ADOTable.ConnectionString:='Provider=SQLOLEDB.1;Data Source=' OpenDialog1.FileName ';Persist Security Info=False';
ADOTable.TableDirect:=True; //直接打开工作表,不作认证
ADOTable.TableName:=SQLSheet; //打开Access工作表
ADOTable.Active:=True; //激活ADO表连接引擎
StringGrid.ColCount:=ADOTable.FieldCount 1;//在StringGrid控件上画字段数(列)表格
StringGrid.RowCount:=ADOTable.RecordCount 1; //记录数(行)
for ARow := 1 to ADOTable.RecordCount 1 do //记录数(行RecordCount)
begin
for ACol := 0 to ADOTable.FieldCount-1 do //字段数(列FieldCount)
StringGrid.Cells[ACol,ARow]:=ADOTable.Fields[ACol].AsString;
ADOTable.Next;
end;
ADOTable.Active:=False; //关闭ADO表连接引擎
end;
//中西字符长度变换函数
function TF_MultiLineRegress.ChEnCharLen(Str:string):integer;
var i,iEnglish,iChinese:integer;
begin
iEnglish:=0;
iChinese:=0;
for i:=1 to Length(Str) do
begin
if ORD(Str[i])<=126 then //ASCII码126以前都是本文码
Inc(iEnglish)
else if ORD(Str[i])>127 then //ASCII码127后面都为汉字编码
Inc(iChinese);
end;
Result:=iEnglish iChinese div 2; //汉字字符为双字节
end;
//StringGrid列变
procedure TF_MultiLineRegress.StrGrdChang(strGrd:TStringGrid);
var i,a:integer;
begin
StrGrd.Cells[0,0]:='序号';
StrGrd.ColWidths[0]:=30;
a:=26*Record_Num 2; //总记录条的高度
if Variable_Num=2 then //二个变量是二维坐标
begin
StrGrd.ColCount:=3;
if a<StrGrd.Height then
StrGrd.ColWidths[1]:=(StrGrd.Width-StrGrd.ColWidths[0])div 2-3
else
StrGrd.ColWidths[1]:=(StrGrd.Width-StrGrd.ColWidths[0])div 2-12;
StrGrd.ColWidths[2]:=StrGrd.ColWidths[1];
StrGrd.Cells[1,0]:='实验变量X';
StrGrd.Cells[2,0]:='实验变量Y';
end else if Variable_Num=3 then //三个变量是三维坐标
begin
StrGrd.ColCount:=4;
if a<StrGrd.Height then
StrGrd.ColWidths[1]:=(StrGrd.Width-StrGrd.ColWidths[0])div 3-2
else
StrGrd.ColWidths[1]:=(StrGrd.Width-StrGrd.ColWidths[0])div 3-8;
StrGrd.ColWidths[2]:=StrGrd.ColWidths[1];
StrGrd.ColWidths[3]:=StrGrd.ColWidths[1];
StrGrd.Cells[1,0]:='实验变量X';
StrGrd.Cells[2,0]:='实验变量Y';
StrGrd.Cells[3,0]:='实验变量Z';
end else if Variable_Num=4 then //四个自变量
begin
StrGrd.ColCount:=5;
if a<StrGrd.Height then
StrGrd.ColWidths[1]:=(StrGrd.Width-StrGrd.ColWidths[0])div 4-2
else
StrGrd.ColWidths[1]:=(StrGrd.Width-StrGrd.ColWidths[0])div 4-6;
StrGrd.ColWidths[2]:=StrGrd.ColWidths[1];
StrGrd.ColWidths[3]:=StrGrd.ColWidths[1];
StrGrd.ColWidths[4]:=StrGrd.ColWidths[1];
StrGrd.Cells[1,0]:='变量Y';
StrGrd.Cells[2,0]:='变量X1';
StrGrd.Cells[3,0]:='变量X2';
StrGrd.Cells[4,0]:='变量X3';
end else //五个以上变量不画图
begin
StrGrd.ColCount:=Variable_Num 1;
StrGrd.ColWidths[1]:=(StrGrd.Width-StrGrd.ColWidths[0])div 4-6;
StrGrd.Cells[1,0]:='变量Y';
for i:=2 to Variable_Num do
begin
StrGrd.ColWidths[i]:=StrGrd.ColWidths[1];
StrGrd.Cells[i,0]:='变量X' inttostr(i-1);
end;
end;
end;
//只能打开一个同子窗口自定义过程
procedure TF_MultiLineRegress.OpenChildForm(FormClass:TFormClass;var Fm;AOwner:TComponent);
var i:integer;
Child:TForm;
begin
for i := 0 to Screen.FormCount – 1 do
begin
if Screen.Forms[i].ClassType=FormClass then
begin
Child:=Screen.Forms[i];
if Child.WindowState=wsMinimized then
ShowWindow(Child.Handle,SW_SHOWNORMAL)
else
ShowWindow(Child.Handle,SW_SHOWNA);
if (not Child.Visible) then Child.Visible:=True;
Child.BringToFront;
Child.SetFocus;
TForm(Fm):=Child;
Exit;
end;
end;
Child:=TForm(FormClass.NewInstance);
TForm(Fm):=Child;
Child.Create(AOwner);
end;
//系统初始化
procedure TF_MultiLineRegress.FormCreate(Sender: TObject);
var year,month,day:word;
begin
//LoginInitialize; //注册初始值(打开便激活注册)
DoubleBuffered:=True; //获取双倍缓存
TRollThread:=TRollFontThread.Create(True);//创建滚动线程
TRollThread.Resume; //唤醒该线程继续执行
ReadWriteIniFile; //读初始文件
B_AnalysSel:=False; //分析选择开关,只有使用了"分析选择"才能运行"执行操作"
AnalyseSelect_k:=False; //AnalyseSelect子窗口没有打开
k:=0;
drawK:=False; //表示曲线没有画
RunNum:=0; //未注册的运行次数
StatusBar1.Panels[1].Text:='『最小二乘曲线拟合』';
//显示年月日周
Decodedate(now,year,month,day);
StatusBar1.Panels[2].Text:=' ' inttostr(year) '年'
inttostr(month) '月' inttostr(day) '日' ' ' f_get_week;
end;
//自定义星期函数
Function TF_MultiLineRegress.f_get_week:shortString;
var days:array[1..7] of ShortString; //字符型天数一维静态数组
begin
days[1]:='星期日';
days[2]:='星期一';
days[3]:='星期二';
days[4]:='星期三';
days[5]:='星期四';
days[6]:='星期五';
days[7]:='星期六';
result:=days[DayOfWeek(now)]; //周日期函数DayOfWeek(now)返回值1~7,星期天为1
end;
//注册初始值(取机器码后两组数与19581129345异或,再取从右至左11位字符作为第一次机器密码)
Procedure TF_MultiLineRegress.LoginInitialize;
begin
MachineCode0:=RightStr(inttostr((GetCPUID[3] GetCPUID[4])xor 19581129345),11);
MachineCode1:=Serial(strtoint64(MachineCode0)); //第二次加密码
//比较注册表中注册码与机器码是否相同,确定合法用户
ReadRegistry; //调'读注册表'过程
if LoginCode=MachineCode1 then //注册用户
begin
NoRegistry:=False; //打开注册开关
F_MultiLineRegress.Caption:='【拟合平滑回归分析】 ——注册版,谢谢您对正版软件的支持!';
Timer1.Enabled:=True;
end else
begin
NoRegistry:=True; //没有注册
ShowMessage(' 试用版,使用次数有限。谢谢您使用该软件!');
F_MultiLineRegress.Caption:='【拟合平滑回归分析】 ——试用版,使用次数不能超过20次,谢谢!';
if RunNum>19 then
begin
SpeedButton3.Enabled:=False; //执行操作按钮失效
ShowMessage('您使用该软件超过了20次,' #13 #10 '敬请注册。谢谢您的支持!');
end else
begin
RunNum:=RunNum 1;
WriteRegistry;//写注册表过程
F_MultiLineRegress.Caption:='【拟合平滑回归分析】 ——试用版,这是您第' inttostr(RunNum) '次使用!';
end;
end;
end;
//读注册表过程
Procedure TF_MultiLineRegress.ReadRegistry;
var MyRegistry:TRegistry;
begin
MyRegistry:=TRegistry.Create; //创建注册表实例
MyRegistry.RootKey:=HKEY_LOCAL_MACHINE; //指定注册表根键路由
if MyRegistry.OpenKey('SoftWareP_MultiLineRegress',True)then//注册根键有则打开,无则创建
begin
if MyRegistry.ValueExists('LoginCode') then //若根值存在
LoginCode:=MyRegistry.ReadString('LoginCode'); //取注册号码
if MyRegistry.ValueExists('RunNumber') then //若根值中运行次数存在
RunNum:=strtoint(MyRegistry.ReadString('RunNumber')); //取运行次数
end;
MyRegistry.CloseKey; //关闭注册表主要路由
MyRegistry.Free; //释放注册表实例
end;
//写注册表过程
Procedure TF_MultiLineRegress.WriteRegistry;
var MyRegistry:TRegistry;
begin
MyRegistry:=TRegistry.Create; //创建注册表实例
MyRegistry.RootKey:=HKEY_LOCAL_MACHINE; //指定注册表根键路由
if MyRegistry.OpenKey('SoftWareP_MultiLineRegress',True)then
begin //打开关键词目录,若关键名不存在则创建
MyRegistry.WriteString('RunNumber',inttostr(RunNum));//将用户注册码写入注册表
end;
MyRegistry.CloseKey; //关闭注册表主要路由
MyRegistry.Free; //释放注册表实例
end;
//加密函数
function TF_MultiLineRegress.Serial(Num:DWORD):string;
var sNum:string;
inChar:array[1..4]of char;
begin
sNum:=inttostr(Num xor 1310231986); //对双字符异或转为数字型
inChar[1]:=char(((integer(sNum[1]) integer(sNum[2]))mod 5) integer('a'));
inChar[2]:=char(((integer(sNum[3]) integer(sNum[4]))mod 5) integer('a'));
inChar[3]:=char(((integer(sNum[5]) integer(sNum[6]))mod 5) integer('a'));
inChar[4]:=char(((integer(sNum[7]) integer(sNum[8]) integer(sNum[9]))mod 5) integer('a'));
insert(inChar[1],sNum,1);
insert(inChar[4],sNum,3);
insert(inChar[2],sNum,5);
insert(inChar[3],sNum,9);
Result:=sNum;
end;
//读写初始文件
Procedure TF_MultiLineRegress.ReadWriteIniFile;
var filename:shortstring;
MyIniFile:TIniFile;
i:integer;
begin
filename:=ExtractFilePath(paramstr(0)) 'config.ini';
MyIniFile:=TIniFile.Create(filename);
if FileExists(filename) then //若初始文件存在,读初始值
begin
Variable_Num:=strtoint(MyIniFile.Readstring('VariableNum','Variable_Num',filename));//选择坐标类型
Record_Num:=strtoint(MyIniFile.Readstring('RecordNum','Record_Num',filename));//记录条数
CoordX_min:=strtofloat(MyIniFile.Readstring('CoordXmin','CoordX_min',filename));//X坐标最小值
CoordX_max:=strtofloat(MyIniFile.Readstring('CoordXmax','CoordX_max',filename));//X坐标最大值
CoordY_min:=strtofloat(MyIniFile.Readstring('CoordYmin','CoordY_min',filename));//Y坐标最小值
CoordY_max:=strtofloat(MyIniFile.Readstring('CoordYmax','CoordY_max',filename));//Y坐标最大值
CoordZ_min:=strtofloat(MyIniFile.Readstring('CoordZmin','CoordZ_min',filename));//Z坐标最小值
CoordZ_max:=strtofloat(MyIniFile.Readstring('CoordZmax','CoordZ_max',filename));//Z坐标最大值
DrawX_min:=strtofloat(MyIniFile.Readstring('DrawXmin','DrawX_min',filename));//X绘图最小值
DrawX_max:=strtofloat(MyIniFile.Readstring('DrawXmax','DrawX_max',filename));//X绘图最大值
DrawY_min:=strtofloat(MyIniFile.Readstring('DrawYmin','DrawY_min',filename));//Y绘图最小值
DrawY_max:=strtofloat(MyIniFile.Readstring('DrawYmax','DrawY_max',filename));//Y绘图最大值
DrawZ_min:=strtofloat(MyIniFile.Readstring('DrawZmin','DrawZ_min',filename));//Z绘图最小值
DrawZ_max:=strtofloat(MyIniFile.Readstring('DrawZmax','DrawZ_max',filename));//Z绘图最大值
Width1:=strtoint(MyIniFile.Readstring('CoordWidth','Coord_width',filename));//坐标线宽
Width2:=strtoint(MyIniFile.Readstring('CurveWidth','Curve_width',filename));//曲线线宽
Width3:=strtoint(MyIniFile.Readstring('DataWidth','Data_width',filename));//曲线线宽
DrawX_step:=strtoint(MyIniFile.Readstring('DrawXstep','DrawX_step',filename));//X方向网格宽
DrawY_step:=strtoint(MyIniFile.Readstring('DrawYstep','DrawY_step',filename));//Y方向网格宽
CoordXY_Angle:=strtofloat(MyIniFile.Readstring('CoordXYAngle','CoordXY_Angle',filename));//XY夹角
Color1:=strtoint(MyIniFile.Readstring('BockGroundColor','BockGround_color',filename));//背景颜色
Color2:=strtoint(MyIniFile.Readstring('CoordinateColor','Coordinate_color',filename));//坐标颜色
Color3:=strtoint(MyIniFile.Readstring('CurveColor','Curve_color',filename));//曲线颜色
Color4:=strtoint(MyIniFile.Readstring('DataColor','Data_color',filename));//数据颜色
end else //若初始文件不在,先给初值,再写入初始文件
begin
Variable_Num:=2;
Record_Num:=1;
CoordX_min:=-8;
CoordX_max:=8;
CoordY_min:=-8;
CoordY_max:=8;
CoordZ_min:=-8;
CoordZ_max:=8;
DrawX_min:=-6;
DrawX_max:=6;
DrawY_min:=-6;
DrawY_max:=6;
DrawZ_min:=-6;
DrawZ_max:=6;
Width1:=1;
Width2:=1;
Width3:=1;
DrawX_step:=1;
DrawY_step:=1;
CoordXY_Angle:=45; //三维坐标中XY坐标夹角
Color1:=clYellow;
Color2:=clBlue;
Color3:=clRed;
Color4:=clGreen;
MyIniFile.Writeinteger('VariableNum','Variable_Num',Variable_Num);
MyIniFile.Writeinteger('RecordNum','Record_Num',Record_Num);
MyIniFile.WriteFloat('CoordXmin','CoordX_min',CoordX_min);
MyIniFile.WriteFloat('CoordXmax','CoordX_max',CoordX_max);
MyIniFile.WriteFloat('CoordYmin','CoordY_min',CoordY_min);
MyIniFile.WriteFloat('CoordYmax','CoordY_max',CoordY_max);
MyIniFile.WriteFloat('CoordZmin','CoordZ_min',CoordZ_min);
MyIniFile.WriteFloat('CoordZmax','CoordZ_max',CoordZ_max);
MyIniFile.WriteFloat('DrawXmin','DrawX_min',DrawX_min);
MyIniFile.WriteFloat('DrawXmax','DrawX_max',DrawX_max);
MyIniFile.WriteFloat('DrawYmin','DrawY_min',DrawY_min);
MyIniFile.WriteFloat('DrawYmax','DrawY_max',DrawY_max);
MyIniFile.WriteFloat('DrawZmin','DrawZ_min',DrawZ_min);
MyIniFile.WriteFloat('DrawZmax','DrawZ_max',DrawZ_max);
MyIniFile.WriteInteger('CoordWidth','Coord_width',Width1);
MyIniFile.WriteInteger('CurveWidth','Curve_width',Width2);
MyIniFile.WriteInteger('DataWidth','Data_width',Width3);
MyIniFile.WriteInteger('DrawXstep','DrawX_step',DrawX_step);
MyIniFile.WriteInteger('DrawYstep','DrawY_step',DrawY_step);
MyIniFile.WriteFloat('CoordXYAngle','CoordXY_Angle',CoordXY_Angle);
MyIniFile.WriteInteger('BockGroundColor','BockGround_color',Color1);
MyIniFile.WriteInteger('CoordinateColor','Coordinate_color',Color2);
MyIniFile.WriteInteger('CurveColor','Curve_color',Color3);
MyIniFile.WriteInteger('DataColor','Data_color',Color4);
end;
StringGrid1.RowCount:=Record_Num 1;
for i:=1 to Record_Num do StringGrid1.Cells[0,i]:=inttostr(i);
Label2.Caption:='[' inttostr(Variable_Num) '个变量]';
MyIniFile.Free;
end;
//计算坐标初始值
procedure TF_MultiLineRegress.CoordInitValue;
begin
//以下是建立坐标系统的基本参数
//下面-2是使绘图实际宽高小一点,不要顶格绘制, 1是增加一个世界坐标宽高度,便于坐标箭头显示
X_num:=Trunc((Image1.Width)/(Abs(CoordX_max-CoordX_min) 1));//X轴单位坐标宽刻度像素数
Z_num:=Trunc((Image1.Height)/(Abs(CoordZ_max-CoordZ_min) 1));//Z轴单位坐标高刻度像素数
Y_num:=Trunc(sqrt(X_num*X_num Z_num*Z_num)*cos(CoordXY_Angle*pi/180)/sqrt(2));//Y轴单位坐标高刻度像素数
X_0:=Trunc(X_num*Abs(CoordX_min-0.5)); //世界坐标原点在屏幕右移2的像素数 2
Z_0:=Trunc(Image1.Height-Z_num*Abs(CoordZ_min-0.5)); //世界坐标原点在屏幕上移2的像素数-2
end;
//世界坐标转为屏幕坐标函数
function TF_MultiLineRegress.WorldToScreen(var xworld,yworld,zworld:Double):TCoordiateRecord;
begin
CoordInitValue;//调用坐标基本初始值原点X_0及单位坐标像素数X_num
//注意:下面yworld前面的符号决定了正Y轴方向!
WorldToScreen.xscreen:=Round(X_0 xworld*X_num-yworld*Y_num*cos(CoordXY_Angle*pi/180));
WorldToScreen.zscreen:=Round(Z_0-zworld*Z_num yworld*Y_num*sin(CoordXY_Angle*pi/180));
end;
//画线段过程
procedure TF_MultiLineRegress.DrawLine(var x1world,y1world,z1world,x2world,y2world,z2world:Double);
var x1screen,z1screen,x2screen,z2screen:integer; //在屏幕上画的屏幕坐标点
begin
x1screen:=WorldToScreen(x1world,y1world,z1world).xscreen;
z1screen:=WorldToScreen(x1world,y1world,z1world).zscreen;
x2screen:=WorldToScreen(x2world,y2world,z2world).xscreen;
z2screen:=WorldToScreen(x2world,y2world,z2world).zscreen;
Image1.Canvas.MoveTo(x1screen,z1screen);
Image1.Canvas.LineTo(x2screen,z2screen);
end;
//把实验数据点画为‘ ‘号
procedure TF_MultiLineRegress.DrawCrossLine(var xworld,yworld,zworld:Double;Color:TColor);
var x1world,y1world,z1world,x2world,y2world,z2world:Double;
begin
Image1.Canvas.Pen.Width:=Width3;//数据线宽度
Image1.Canvas.Pen.Color:=Color;//数据颜色
Image1.Canvas.Pen.Style:=PSSolid;//坐标为实线
if Variable_Num=2 then yworld:=0; //若为二维平面坐标系
x1world:=xworld-(CoordX_max-CoordX_min)/120;
x2world:=xworld (CoordX_max-CoordX_min)/120;
if Variable_Num=3 then //若为三维立体坐标系
begin
y1world:=yworld-(CoordY_max-CoordY_min)/120;
y2world:=yworld (CoordY_max-CoordY_min)/120;
end;
z1world:=zworld-(CoordZ_max-CoordZ_min)/120;
z2world:=zworld (CoordZ_max-CoordZ_min)/120;
DrawLine(x1world,yworld,zworld,x2world,yworld,zworld); //画X轴
if Variable_Num=3 then DrawLine(xworld,y1world,zworld,xworld,y2world,zworld); //画Y轴
DrawLine(xworld,yworld,z1world,xworld,yworld,z2world); //画X轴
end;
//画箭头过程
procedure TF_MultiLineRegress.ArrowHead(var x1world,y1world,z1world,x2world,y2world,z2world:Double);
var x1screen,z1screen,x2screen,z2screen,x3screen,z3screen:integer;//在屏幕上画的屏幕坐标点
Axscreen,Azscreen:integer; //矢量屏幕坐标差
α,AAscreen:Double; //矢量的屏幕模值与X屏幕坐标的夹角
begin
x1screen:=WorldToScreen(x1world,y1world,z1world).xscreen;
z1screen:=WorldToScreen(x1world,y1world,z1world).zscreen;
x2screen:=WorldToScreen(x2world,y2world,z2world).xscreen;
z2screen:=WorldToScreen(x2world,y2world,z2world).zscreen;
Axscreen:=x2screen-x1screen;
Azscreen:=z2screen-z1screen;
AAscreen:=sqrt(Axscreen*Axscreen Azscreen*Azscreen);
α:=0;
if((Axscreen>0)and(Azscreen>0))or((Axscreen<0)and(Azscreen>0))then //一二象限
begin
α:=arccos(Axscreen/AAscreen);
end else if((Axscreen<0)and(Azscreen<0))or((Axscreen>0)and(Azscreen<0))then//三四象限
begin
α:=2*pi-arccos(Axscreen/AAscreen);
end else if(Axscreen=0)and(Azscreen>0)then
begin
α:=pi/2;
end else if(Axscreen=0)and(Azscreen<0)then
begin
α:=pi*3/2;
end else if(Axscreen>0)and(Azscreen=0)then
begin
α:=0;
end else if(Axscreen<0)and(Azscreen=0)then
begin
α:=pi;
end;
//画上边斜线
x3screen:=Round(x2screen-15*cos(α 15*pi/180));
z3screen:=Round(z2screen-15*sin(α 15*pi/180));
Image1.Canvas.MoveTo(x2screen,z2screen);
Image1.Canvas.LineTo(x3screen,z3screen);
//画下边斜线
x3screen:=Round(x2screen-15*cos(α-15*pi/180));
z3screen:=Round(z2screen-15*sin(α-15*pi/180));
Image1.Canvas.MoveTo(x2screen,z2screen);
Image1.Canvas.LineTo(x3screen,z3screen);
end;
//画刻度及标尺过程
procedure TF_MultiLineRegress.Scale(var x1world,y1world,z1world,
x2world,y2world,z2world:Double;a,b:smallint);//a,b是线段画刻度的起始值
var Axworld,Ayworld,Azworld,AAworld:Double;
x1screen,z1screen,x2screen,z2screen,x3screen,z3screen:integer;//在屏幕上画的屏幕坐标点
Axscreen,Azscreen,num:integer; //矢量屏幕坐标差,Anum单位矢量像素数
α,AAscreen:Double; //矢量的屏幕模值与X屏幕坐标的夹角
i:smallint;
begin
Axworld:=x2world-x1world;
Ayworld:=y2world-y1world;
Azworld:=z2world-z1world;
AAworld:=sqrt(Axworld*Axworld Ayworld*Ayworld Azworld*Azworld);
x1screen:=WorldToScreen(x1world,y1world,z1world).xscreen;
z1screen:=WorldToScreen(x1world,y1world,z1world).zscreen;
x2screen:=WorldToScreen(x2world,y2world,z2world).xscreen;
z2screen:=WorldToScreen(x2world,y2world,z2world).zscreen;
Axscreen:=x2screen-x1screen;
Azscreen:=z2screen-z1screen;
AAscreen:=sqrt(Axscreen*Axscreen Azscreen*Azscreen);
num:=Trunc(AAscreen/AAworld); //单位矢量像素数
α:=0;
if((Axscreen>0)and(Azscreen>0))or((Axscreen<0)and(Azscreen>0))then //一二象限
begin
α:=2*pi-arccos(Axscreen/AAscreen);
end else if((Axscreen<0)and(Azscreen<0))or((Axscreen>0)and(Azscreen<0))then//三四象限
begin
α:=pi arccos(Axscreen/AAscreen);
end else if((Axscreen=0)and(Azscreen>0))or((Axscreen=0)and(Azscreen<0))then //Y轴
begin
α:=pi/2;
end else if((Axscreen>0)and(Azscreen=0))or((Axscreen<0)and(Azscreen=0))then //X轴
begin
α:=0;
end;
for i := a to b do //画刻度
begin
x2screen:=Round(x1screen i*num*cos(α));
z2screen:=Round(z1screen-i*num*sin(α));
if y_Axis=True then //若画Y轴,该变量仅用于此
begin
x3screen:=x2screen; //所有Y轴方向刻度都向上
z3screen:=Round(z2screen-15*sin(α pi));
end else begin
x3screen:=Round(x2screen-10*cos(α pi/2));
z3screen:=Round(z2screen-10*sin(α pi/2));
end;
Image1.Canvas.MoveTo(x2screen,z2screen);
Image1.Canvas.LineTo(x3screen,z3screen);
//在刻度下写坐标值
if(Axscreen>0)and(Azscreen=0)then //X正轴
begin
Image1.Canvas.TextOut(x2screen-2,z2screen 1,inttostr(i));
end else if(Axscreen<0)and(Azscreen=0)then //X负轴
begin
Image1.Canvas.TextOut(x2screen-6,z2screen 1,inttostr(i));
end else if(Axscreen=0)and(Azscreen<0)then //Z正轴
begin
Image1.Canvas.TextOut(x2screen-13,z2screen-6,inttostr(i));
end else if(Axscreen=0)and(Azscreen>0)then //Z负轴
begin
Image1.Canvas.TextOut(x2screen-18,z2screen-6,inttostr(i));
end else begin //Y正负轴
Image1.Canvas.TextOut(x2screen 2,z2screen 2,inttostr(i));
end;
end;
end;
//窗口变化
procedure TF_MultiLineRegress.FormResize(Sender: TObject);
begin
Panel1.Height:=F_MultiLineRegress.Height-53;
Panel1.Width:=Panel1.Height;
Image1.Height:=Panel1.Height-10;
Image1.Width:=Image1.Height;
Image1.Top:=5;
Image1.Left:=5;
Panel2.Width:=StatusBar1.Width-Panel1.Width;
Panel2.Height:=Panel1.Height;
Label100.Left:=2;
ProgressBar1.Left:=2;
SpeedButton1.Width:=Round(ToolBar1.Width/6);
SpeedButton2.Width:=SpeedButton1.Width;
SpeedButton3.Width:=SpeedButton1.Width;
SpeedButton4.Width:=SpeedButton1.Width;
SpeedButton5.Width:=SpeedButton1.Width;
SpeedButton6.Width:=ToolBar1.Width-SpeedButton1.Width*5;
GroupBox1.Width:=Panel5.Width-10;
GroupBox1.Top:=15;
GroupBox1.Left:=5;
GroupBox1.Height:=(Panel5.Height-35)div 2;
Button2.Top:=15;
Button1.Top:=Button2.Top;
Button2.Left:=GroupBox1.Width-Button2.Width-10;
Button1.Left:=Button2.Left-Button1.Width;
Button6.Top:=GroupBox1.Height-Button6.Height-7;
Button5.Top:=Button6.Top;
Button4.Top:=Button6.Top;
Button6.Left:=GroupBox1.Width-Button6.Width-10;
Button5.Left:=Button6.Left-Button5.Width;
Button4.Left:=Button5.Left-Button4.Width;
StringGrid1.Width:=GroupBox1.Width-20;
StringGrid1.Height:=GroupBox1.Height-Button2.Height-Button6.Height-30;
StringGrid1.Top:=Button2.Top Button2.Height 4;
StringGrid1.Left:=10;
Label2.Top:=Button6.Top 5;
StrGrdChang(StringGrid1); //StringGrid列变
GroupBox2.Width:=GroupBox1.Width;
GroupBox2.Top:=GroupBox1.Height 25;
GroupBox2.Left:=5;
GroupBox2.Height:=GroupBox1.Height;
Memo1.Width:=GroupBox2.Width-10;
Memo1.Height:=GroupBox2.Height-20;
Memo1.Top:=15;
Memo1.Left:=5;
Panel3.Width:=Panel2.Width-2;
ProgressBar1.Width:=Panel3.Width-10;
ProgressBar1.Left:=1;
//注册帮助栏显示位置
Panel6.Top:=(Panel1.Height-Panel6.Height)div 2;
Panel6.Left:=(Panel1.Width-Panel6.Width)div 2;
end;
//退出系统
procedure TF_MultiLineRegress.SpeedButton6Click(Sender: TObject);
begin
Close;
end;
//释放内存
procedure TF_MultiLineRegress.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Action:=cafree;
end;
//写坐标轴标识字过程
procedure TF_MultiLineRegress.WriteCoordinateName(var xworld,yworld,zworld:Double;
Ax,Ay:smallint;char:shortstring);
var xscreen,zscreen:integer; //Ax,Ay是字的像素位移值,char是要写的字
begin
xscreen:=WorldToScreen(xworld,yworld,zworld).xscreen;
zscreen:=WorldToScreen(xworld,yworld,zworld).zscreen;
Image1.Canvas.TextOut(xscreen Ax,zscreen Ay,char);
end;
//画背景颜色
procedure TF_MultiLineRegress.BackGroundColor;
begin
Image1.Canvas.Brush.Color:=Color1; //背景.给画布刷子颜色
Image1.Canvas.Pen.Color:=Color1; //背景.给画布画笔颜色
//背景.确认画布大小,才能给背景画颜色
Image1.Canvas.Rectangle(0,0,Image1.Width,Image1.Height);
end;
//画三维坐标
procedure TF_MultiLineRegress.Draw3DCoordinate;
var x1world,y1world,z1world,x2world,y2world,z2world:Double;
a,b:smallint;//写坐标名时,字符的微调XY距离
begin
Image1.Canvas.Pen.Width:=Width1;//坐标线宽度
Image1.Canvas.Pen.Color:=Color2;//坐标线颜色
Image1.Canvas.Pen.Style:=PSSolid;//坐标为实线
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//初始激活
x1world:=0;y1world:=0;z1world:=0;//世界坐标原点
Image1.Cursor:=crdefault; //若是立体坐标,则使用默认鼠标图形
x2world:=CoordX_max 0.5;y2world:=0;z2world:=0;a:=1;b:=Trunc(CoordX_max);
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//正X轴
ArrowHead(x1world,y1world,z1world,x2world,y2world,z2world); //X正轴箭头
Scale(x1world,y1world,z1world,x2world,y2world,z2world,a,b); //刻度
WriteCoordinateName(x2world,y2world,z2world,-28,13,'X坐标');//写X坐标名
WriteCoordinateName(x1world,y1world,z1world,2,1,'0'); //写坐标原点
x2world:=0;y2world:=CoordY_max 0.5;z2world:=0;a:=1;b:=Trunc(CoordY_max);y_Axis:=True;
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//正Y轴
ArrowHead(x1world,y1world,z1world,x2world,y2world,z2world); //Y正轴箭头
Scale(x1world,y1world,z1world,x2world,y2world,z2world,a,b); //刻度
WriteCoordinateName(x2world,y2world,z2world,6, 1,'Y坐标'); //写Y坐标名
y_Axis:=False;
x2world:=0;y2world:=0;z2world:=CoordZ_max 0.5;a:=1;b:=Trunc(CoordZ_max);
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//正Z轴
ArrowHead(x1world,y1world,z1world,x2world,y2world,z2world); //Z正轴箭头
Scale(x1world,y1world,z1world,x2world,y2world,z2world,a,b); //刻度
WriteCoordinateName(x2world,y2world,z2world,-35,3,'Z坐标'); //写Z坐标名
x2world:=CoordX_min-0.5;y2world:=0;z2world:=0;a:=Trunc(CoordX_min);b:=-1;
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//负X轴
Scale(x1world,y1world,z1world,x2world,y2world,z2world,a,b); //刻度
x2world:=0;y2world:=CoordY_min-0.5;z2world:=0;a:=Trunc(CoordY_min);b:=-1;y_Axis:=True;
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//负Y轴
Scale(x1world,y1world,z1world,x2world,y2world,z2world,a,b); //刻度
y_Axis:=False;
x2world:=0;y2world:=0;z2world:=CoordZ_min-0.5;a:=Trunc(CoordZ_min);b:=-1;
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//负Z轴
Scale(x1world,y1world,z1world,x2world,y2world,z2world,a,b); //刻度
end;
//画二维坐标
procedure TF_MultiLineRegress.Draw2DCoordinate;
var x1world,y1world,z1world,x2world,y2world,z2world:Double;
a,b:smallint;//写坐标名时,字符的微调XY距离
begin
Image1.Canvas.Pen.Width:=Width1;//坐标线宽度
Image1.Canvas.Pen.Color:=Color2;//坐标线颜色
Image1.Canvas.Pen.Style:=PSSolid;//坐标为实线
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//初始激活
x1world:=0;y1world:=0;z1world:=0;//世界坐标原点
Image1.Cursor:=crdefault; //若是立体坐标,则使用默认鼠标图形
x2world:=CoordX_max 0.5;y2world:=0;z2world:=0;a:=1;b:=Trunc(CoordX_max);
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//正X轴
ArrowHead(x1world,y1world,z1world,x2world,y2world,z2world); //X正轴箭头
Scale(x1world,y1world,z1world,x2world,y2world,z2world,a,b); //刻度
WriteCoordinateName(x2world,y2world,z2world,-28,13,'X坐标');//写X坐标名
WriteCoordinateName(x1world,y1world,z1world,2,1,'0'); //写坐标原点
x2world:=0;y2world:=0;z2world:=CoordZ_max 0.5;a:=1;b:=Trunc(CoordZ_max);
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//正Z轴
ArrowHead(x1world,y1world,z1world,x2world,y2world,z2world); //Z正轴箭头
Scale(x1world,y1world,z1world,x2world,y2world,z2world,a,b); //刻度
WriteCoordinateName(x2world,y2world,z2world,-35,3,'Y坐标'); //写Z坐标名
x2world:=CoordX_min-0.5;y2world:=0;z2world:=0;a:=Trunc(CoordX_min);b:=-1;
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//负X轴
Scale(x1world,y1world,z1world,x2world,y2world,z2world,a,b); //刻度
x2world:=0;y2world:=0;z2world:=CoordZ_min-0.5;a:=Trunc(CoordZ_min);b:=-1;
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//负Z轴
Scale(x1world,y1world,z1world,x2world,y2world,z2world,a,b); //刻度
end;
//画多项式表达式曲线
procedure TF_MultiLineRegress.DrawMultiCurve(Expre:string;CurveColor:TColor);
var x1world,y1world,z1world,x2world,y2world,z2world,x,y:Double;
i,j,n,m,p,q,s:integer;//n,m是绘X,Y绘图区像素数,p,q是X,Y方向网格数,s是进程条累加数
Expression:TExpress;//函数表达式类
Label L10;
begin
Image1.Canvas.Pen.Width:=Width2;//曲线宽度
Image1.Canvas.Pen.Color:=CurveColor;//曲线颜色
Image1.Canvas.Pen.Style:=PSSolid;//函数为实线
if Abs(DrawX_min)>Abs(CoordX_min)then DrawX_min:=CoordX_min;//若绘图范围大于坐标范围,则绘图范围取坐标范围
if Abs(DrawX_max)>Abs(CoordX_max)then DrawX_max:=CoordX_max;
if Abs(DrawY_min)>Abs(CoordY_min)then DrawY_min:=CoordY_min;
if Abs(DrawY_max)>Abs(CoordY_max)then DrawY_max:=CoordY_max;
Expression:=TExpress.Create(self);//创建字符串转换成表达式类
ProgressBar1.Min:=0; //进度条最小值
if Variable_Num=2 then //平面坐标绘曲线图
begin
n:=Round((DrawX_max-DrawX_min)*X_num); //X绘图区像素数
ProgressBar1.Max:=n;//进度条最大值
y1world:=0;y2world:=0;
TRollThread.Suspend;//挂起滚动显示线程Resume;
Label100.Visible:=False; //关闭滚动显示字符串
ProgressBar1.Visible:=True; //打开进程显示条
for i:=0 to n do
begin
x1world:=DrawX_min ((DrawX_max-DrawX_min)/n)*i; //将屏幕坐标转换成世界坐标
x:=x1world;
Expression.Expression:=Expre;//将字符串给表达式类
if not(Expression.Error) then
begin //由表达式类将字符串转换成表达式后再给变量
z1world:=Expression.TheFunction(x,0,0);//算出函数值的世界坐标
if z1world<DrawZ_min then
begin
z1world:=DrawZ_min;//Z轴绘图范围限制
goto L10;
end;
if z1world>DrawZ_max then
begin
z1world:=DrawZ_max;
goto L10;
end;
end else begin
ShowMessage('非法语法!');
end;
x2world:=DrawX_min ((DrawX_max-DrawX_min)/n)*(i 1);
x:=x2world;
Expression.Expression:=Expre;
if not(Expression.Error) then
begin
z2world:=Expression.TheFunction(x,0,0);
if z2world<DrawZ_min then
begin
z2world:=DrawZ_min;//Z轴绘图范围限制
goto L10;
end;
if z2world>DrawZ_max then
begin
z2world:=DrawZ_max;
goto L10;
end;
end else begin
ShowMessage('非法语法!');
end;
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//画X轴平行线段
L10:
ProgressBar1.Position:=i;
end;
end else if Variable_Num=3 then //立体坐标绘曲面图
begin
n:=Round((DrawX_max-DrawX_min)*X_num);//X绘图区像素数
m:=Round((DrawY_max-DrawY_min)*Y_num);//Y绘图区像素数
p:=Round(n/DrawX_step);//X向每网格像素数
q:=Round(m/DrawY_step);//Y向第网格像素数
ProgressBar1.Max:=n*DrawY_step m*DrawX_step;//总绘图线条数,进度条最大值
TRollThread.Suspend;//挂起滚动显示线程Resume;
Label100.Visible:=False; //关闭滚动显示字符串
ProgressBar1.Visible:=True; //打开进程显示条
j:=0;s:=0;
while j<=m do//画平行X轴的网格线
begin
for i:=0 to n do
begin
x1world:=DrawX_min ((DrawX_max-DrawX_min)/n)*i; //将屏幕坐标转换成世界坐标
y1world:=DrawY_min ((DrawY_max-DrawY_min)/m)*j;
x:=x1world;
y:=y1world;
Expression.Expression:=Expre;//将字符串给表达式类
if not(Expression.Error) then
begin //由表达式类将字符串转换成表达式后再给变量
z1world:=Expression.TheFunction(x,y,0);//算出函数值的世界坐标
if z1world<DrawZ_min then z1world:=DrawZ_min; //Z轴绘图范围限制
if z1world>DrawZ_max then z1world:=DrawZ_max;
end else begin
ShowMessage('非法语法!');
end;
x2world:=DrawX_min ((DrawX_max-DrawX_min)/n)*(i 1);
y2world:=DrawY_min ((DrawY_max-DrawY_min)/m)*j;
x:=x2world;
y:=y2world;
Expression.Expression:=Expre;
if not(Expression.Error) then
begin
z2world:=Expression.TheFunction(x,y,0);
if z2world<DrawZ_min then z2world:=DrawZ_min; //Z轴绘图范围限制
if z2world>DrawZ_max then z2world:=DrawZ_max;
end else begin
ShowMessage('非法语法!');
end;
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//画X轴平行线段
s:=s 1;
ProgressBar1.Position:=s;
end;
j:=j q; //q是Y轴方向每网格像素数
s:=s 1;
ProgressBar1.Position:=s;
end;
j:=0;
while j<=n do //画平行Y轴的网格线
begin
for i:=0 to m do //画Y轴向
begin
x1world:=DrawX_min ((DrawX_max-DrawX_min)/n)*j;
y1world:=DrawY_min ((DrawY_max-DrawY_min)/m)*i;
x:=x1world;
y:=y1world;
Expression.Expression:=Expre;
if not(Expression.Error) then
begin
z1world:=Expression.TheFunction(x,y,0);
if z1world<DrawZ_min then z1world:=DrawZ_min; //Z轴绘图范围限制
if z1world>DrawZ_max then z1world:=DrawZ_max;
end else begin
ShowMessage('非法语法!');
end;
x2world:=DrawX_min ((DrawX_max-DrawX_min)/n)*j;
y2world:=DrawY_min ((DrawY_max-DrawY_min)/m)*(i 1);
x:=x2world;
y:=y2world;
Expression.Expression:=Expre;
if not(Expression.Error) then
begin
z2world:=Expression.TheFunction(x,y,0);
if z2world<DrawZ_min then z2world:=DrawZ_min; //Z轴绘图范围限制
if z2world>DrawZ_max then z2world:=DrawZ_max;
end else begin
ShowMessage('非法语法!');
end;
DrawLine(x1world,y1world,z1world,x2world,y2world,z2world);//画Y轴平行线段
s:=s 1;
ProgressBar1.Position:=s;
end;
j:=j p; //p是X轴方向每网格像素数
s:=s 1;
ProgressBar1.Position:=s;
end;
end;
end;
//暂停或继续滚动
procedure TF_MultiLineRegress.Label7Click(Sender: TObject);
begin
if Timer1.Enabled=True then
Timer1.Enabled:=False
else
Timer1.Enabled:=True;
end;
end.
绘图初始设置(左边程序模块图,右边设计模块图)
unit U_CoordSet;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, IniFiles;
type
TF_CoordSet = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
Button1: TButton;
GroupBox1: TGroupBox;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
Button2: TButton;
GroupBox2: TGroupBox;
Label1: TLabel;
Edit1: TEdit;
Label2: TLabel;
Edit2: TEdit;
Label3: TLabel;
Edit3: TEdit;
Label4: TLabel;
Edit4: TEdit;
Label5: TLabel;
Edit5: TEdit;
Label6: TLabel;
Edit6: TEdit;
GroupBox4: TGroupBox;
Label13: TLabel;
Edit13: TEdit;
Label14: TLabel;
Edit14: TEdit;
GroupBox6: TGroupBox;
Label19: TLabel;
PaintBox1: TPaintBox;
Label20: TLabel;
PaintBox2: TPaintBox;
Label21: TLabel;
PaintBox3: TPaintBox;
ColorDialog1: TColorDialog;
GroupBox3: TGroupBox;
Label22: TLabel;
PaintBox4: TPaintBox;
Label7: TLabel;
Edit7: TEdit;
Label9: TLabel;
Edit9: TEdit;
Label11: TLabel;
Edit11: TEdit;
Label8: TLabel;
Edit8: TEdit;
Label10: TLabel;
Edit10: TEdit;
Label12: TLabel;
Edit12: TEdit;
Label15: TLabel;
Edit15: TEdit;
GroupBox5: TGroupBox;
Label18: TLabel;
Edit18: TEdit;
Label16: TLabel;
Label17: TLabel;
Edit16: TEdit;
Edit17: TEdit;
RadioButton3: TRadioButton;
Panel3: TPanel;
GroupBox7: TGroupBox;
Label23: TLabel;
Edit19: TEdit;
Button3: TButton;
GroupBox8: TGroupBox;
Edit20: TEdit;
Label24: TLabel;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button3Click(Sender: TObject);
procedure RadioButton3Click(Sender: TObject);
procedure PaintBox4Paint(Sender: TObject);
procedure PaintBox4Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure RadioButton2Click(Sender: TObject);
procedure RadioButton1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure PaintBox3Paint(Sender: TObject);
procedure PaintBox2Paint(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
procedure PaintBox3Click(Sender: TObject);
procedure PaintBox2Click(Sender: TObject);
procedure PaintBox1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
F_CoordSet: TF_CoordSet;
implementation
uses U_MultiLineRegress,U_AnalyseSelect;
{$R *.dfm}
//确定
procedure TF_CoordSet.Button1Click(Sender: TObject);
var filename:shortstring;
MyIniFile:TIniFile;
i:integer;
begin
F_MultiLineRegress.Record_Num:=strtointdef(Edit20.Text,1);//实验记录数
F_MultiLineRegress.StringGrid1.RowCount:=F_MultiLineRegress.Record_Num 1;
for i:=1 to F_MultiLineRegress.Record_Num do
F_MultiLineRegress.StringGrid1.Cells[0,i]:=inttostr(i);
filename:=ExtractFilePath(paramstr(0)) 'config.ini';
MyIniFile:=TIniFile.Create(filename);
MyIniFile.WriteInteger('RecordNum','Record_Num',F_MultiLineRegress.Record_Num);
if RadioButton1.Checked=True then //二维平面坐标
begin
F_MultiLineRegress.Width1:=strtoint(Edit13.Text); //坐标曲线线宽
F_MultiLineRegress.Width2:=strtoint(Edit14.Text);
F_MultiLineRegress.Width3:=strtoint(Edit15.Text);
F_MultiLineRegress.Color1:=PaintBox1.Canvas.Brush.Color;
F_MultiLineRegress.Color2:=PaintBox2.Canvas.Brush.Color;
F_MultiLineRegress.Color3:=PaintBox3.Canvas.Brush.Color;
F_MultiLineRegress.Color4:=PaintBox4.Canvas.Brush.Color;
MyIniFile.WriteInteger('CoordWidth','Coord_width',F_MultiLineRegress.Width1);
MyIniFile.WriteInteger('CurveWidth','Curve_width',F_MultiLineRegress.Width2);
MyIniFile.WriteInteger('DataWidth','Data_width',F_MultiLineRegress.Width3);
MyIniFile.WriteInteger('BockGroundColor','BockGround_color',F_MultiLineRegress.Color1);
MyIniFile.WriteInteger('CoordinateColor','Coordinate_color',F_MultiLineRegress.Color2);
MyIniFile.WriteInteger('CurveColor','Curve_color',F_MultiLineRegress.Color3);
MyIniFile.WriteInteger('DataColor','Data_color',F_MultiLineRegress.Color4);
F_MultiLineRegress.Variable_Num:=2;
F_MultiLineRegress.CoordX_min:=strtofloatdef(Edit1.Text,0);//X坐标范围
F_MultiLineRegress.CoordX_max:=strtofloatdef(Edit2.Text,0);
F_MultiLineRegress.CoordZ_min:=strtofloatdef(Edit5.Text,0);//Y坐标范围
F_MultiLineRegress.CoordZ_max:=strtofloatdef(Edit6.Text,0);
F_MultiLineRegress.DrawX_min:=strtofloatdef(Edit7.Text,0);//X绘图范围
F_MultiLineRegress.DrawX_max:=strtofloatdef(Edit8.Text,0);
F_MultiLineRegress.DrawZ_min:=strtofloatdef(Edit11.Text,0);//Z绘图范围
F_MultiLineRegress.DrawZ_max:=strtofloatdef(Edit12.Text,0);
MyIniFile.WriteInteger('VariableNum','Variable_Num',F_MultiLineRegress.Variable_Num);
MyIniFile.WriteFloat('CoordXmin','CoordX_min',F_MultiLineRegress.CoordX_min);
MyIniFile.WriteFloat('CoordXmax','CoordX_max',F_MultiLineRegress.CoordX_max);
MyIniFile.WriteFloat('CoordZmin','CoordZ_min',F_MultiLineRegress.CoordZ_min);
MyIniFile.WriteFloat('CoordZmax','CoordZ_max',F_MultiLineRegress.CoordZ_max);
MyIniFile.WriteFloat('DrawXmin','DrawX_min',F_MultiLineRegress.DrawX_min);
MyIniFile.WriteFloat('DrawXmax','DrawX_max',F_MultiLineRegress.DrawX_max);
MyIniFile.WriteFloat('DrawZmin','DrawZ_min',F_MultiLineRegress.DrawZ_min);
MyIniFile.WriteFloat('DrawZmax','DrawZ_max',F_MultiLineRegress.DrawZ_max);
end else if RadioButton2.Checked=True then //三维立体坐标
begin
F_MultiLineRegress.Width1:=strtoint(Edit13.Text); //坐标曲线线宽
F_MultiLineRegress.Width2:=strtoint(Edit14.Text);
F_MultiLineRegress.Width3:=strtoint(Edit15.Text);
F_MultiLineRegress.Color1:=PaintBox1.Canvas.Brush.Color;
F_MultiLineRegress.Color2:=PaintBox2.Canvas.Brush.Color;
F_MultiLineRegress.Color3:=PaintBox3.Canvas.Brush.Color;
F_MultiLineRegress.Color4:=PaintBox4.Canvas.Brush.Color;
MyIniFile.WriteInteger('CoordWidth','Coord_width',F_MultiLineRegress.Width1);
MyIniFile.WriteInteger('CurveWidth','Curve_width',F_MultiLineRegress.Width2);
MyIniFile.WriteInteger('DataWidth','Data_width',F_MultiLineRegress.Width3);
MyIniFile.WriteInteger('BockGroundColor','BockGround_color',F_MultiLineRegress.Color1);
MyIniFile.WriteInteger('CoordinateColor','Coordinate_color',F_MultiLineRegress.Color2);
MyIniFile.WriteInteger('CurveColor','Curve_color',F_MultiLineRegress.Color3);
MyIniFile.WriteInteger('DataColor','Data_color',F_MultiLineRegress.Color4);
F_MultiLineRegress.Variable_Num:=3;
F_MultiLineRegress.CoordX_min:=strtofloatdef(Edit1.Text,0);//X坐标范围
F_MultiLineRegress.CoordX_max:=strtofloatdef(Edit2.Text,0);
F_MultiLineRegress.CoordY_min:=strtofloatdef(Edit3.Text,0);//Y坐标范围
F_MultiLineRegress.CoordY_max:=strtofloatdef(Edit4.Text,0);
F_MultiLineRegress.CoordZ_min:=strtofloatdef(Edit5.Text,0);//Z坐标范围
F_MultiLineRegress.CoordZ_max:=strtofloatdef(Edit6.Text,0);
F_MultiLineRegress.DrawX_min:=strtofloatdef(Edit7.Text,0);//X绘图范围
F_MultiLineRegress.DrawX_max:=strtofloatdef(Edit8.Text,0);
F_MultiLineRegress.DrawY_min:=strtofloatdef(Edit9.Text,0);//Y绘图范围
F_MultiLineRegress.DrawY_max:=strtofloatdef(Edit10.Text,0);
F_MultiLineRegress.DrawZ_min:=strtofloatdef(Edit11.Text,0);//Z绘图范围
F_MultiLineRegress.DrawZ_max:=strtofloatdef(Edit12.Text,0);
F_MultiLineRegress.DrawX_step:=strtointdef(Edit16.Text,0);
F_MultiLineRegress.Drawy_step:=strtointdef(Edit17.Text,0);
F_MultiLineRegress.CoordXY_Angle:=strtofloatdef(Edit18.Text,0);//坐标XY夹角
MyIniFile.WriteInteger('VariableNum','Variable_Num',F_MultiLineRegress.Variable_Num);
MyIniFile.WriteFloat('CoordXmin','CoordX_min',F_MultiLineRegress.CoordX_min);
MyIniFile.WriteFloat('CoordXmax','CoordX_max',F_MultiLineRegress.CoordX_max);
MyIniFile.WriteFloat('CoordYmin','CoordY_min',F_MultiLineRegress.CoordY_min);
MyIniFile.WriteFloat('CoordYmax','CoordY_max',F_MultiLineRegress.CoordY_max);
MyIniFile.WriteFloat('CoordZmin','CoordZ_min',F_MultiLineRegress.CoordZ_min);
MyIniFile.WriteFloat('CoordZmax','CoordZ_max',F_MultiLineRegress.CoordZ_max);
MyIniFile.WriteFloat('DrawXmin','DrawX_min',F_MultiLineRegress.DrawX_min);
MyIniFile.WriteFloat('DrawXmax','DrawX_max',F_MultiLineRegress.DrawX_max);
MyIniFile.WriteFloat('DrawYmin','DrawY_min',F_MultiLineRegress.DrawY_min);
MyIniFile.WriteFloat('DrawYmax','DrawY_max',F_MultiLineRegress.DrawY_max);
MyIniFile.WriteFloat('DrawZmin','DrawZ_min',F_MultiLineRegress.DrawZ_min);
MyIniFile.WriteFloat('DrawZmax','DrawZ_max',F_MultiLineRegress.DrawZ_max);
MyIniFile.WriteInteger('DrawXstep','DrawX_step',F_MultiLineRegress.DrawX_step);
MyIniFile.WriteInteger('DrawYstep','DrawY_step',F_MultiLineRegress.DrawY_step);
MyIniFile.WriteFloat('CoordXYAngle','CoordXY_Angle',F_MultiLineRegress.CoordXY_Angle);
end else if RadioButton3.Checked=True then //高维坐标系
begin
F_MultiLineRegress.Variable_Num:=strtointdef(Edit19.Text,0);//变量数目
MyIniFile.WriteInteger('VariableNum','Variable_Num',F_MultiLineRegress.Variable_Num);
end;
MyIniFile.Free;
F_MultiLineRegress.StrGrdChang(F_MultiLineRegress.StringGrid1); //StringGrid列变
F_MultiLineRegress.Label2.Caption:='[' inttostr(F_MultiLineRegress.Variable_Num) '个数据]';
//AnalyseSelect窗口操作
if F_MultiLineRegress.AnalyseSelect_k=True then //若AnalyseSelect子窗口打开
begin
with F_AnalyseSelect do
begin
if F_MultiLineRegress.Variable_Num=2 then //若选择二维坐标
begin
GroupBox1.Caption:='拟合平滑回归方法选择(二维坐标):';
RadioButton1.Enabled:=True; //最小二乘曲线(是二维)
RadioButton2.Enabled:=False; //最小二乘曲面(是三维)
RadioButton3.Enabled:=True; //切比雪夫拟合(是二维)
RadioButton4.Enabled:=True; //最佳一致逼近(是二维)
RadioButton5.Enabled:=True; //一元线性回归(是二维)
RadioButton6.Enabled:=False; //多元线性回归(是三高维)
RadioButton7.Enabled:=False; //逐步回归(三维以上)
RadioButton8.Enabled:=True; //五点三次平滑(二维)
CheckBox1.Enabled:=True; //画拟合多项式图
CheckBox2.Enabled:=True; //画参考模拟函数图
CheckBox3.Enabled:=True; //X值取平均值
CheckBox4.Enabled:=False; //Y值取平均值
Label1.Enabled:=True;Edit1.Enabled:=True;//X数据点个数
Label1.Visible:=True;Edit1.Visible:=True;
Label2.Visible:=False;Edit2.Visible:=False;//Y数据点个数
Label3.Visible:=True;Edit3.Visible:=True;//X最高次幂数
Label4.Visible:=False;Edit4.Visible:=False;//Y最高次幂数
Label5.Visible:=True;Edit5.Visible:=True;//参考模拟函数
end else if F_MultiLineRegress.Variable_Num=3 then //若选择三维坐标
begin
GroupBox1.Caption:='拟合平滑回归方法选择(三维坐标):';
RadioButton1.Enabled:=False; //最小二乘曲线(是二维)
RadioButton2.Enabled:=True; //最小二乘曲面(是三维)
RadioButton3.Enabled:=False; //切比雪夫拟合(是二维)
RadioButton4.Enabled:=False; //最佳一致逼近(是二维)
RadioButton5.Enabled:=False; //一元线性回归(是二维)
RadioButton6.Enabled:=True; //多元线性回归(是三高维)
RadioButton7.Enabled:=False; //逐步回归(三维以上)
RadioButton8.Enabled:=False; //五点三次平滑(二维)
CheckBox1.Enabled:=True; //画拟合多项式图
CheckBox2.Enabled:=True; //画参考模拟函数图
CheckBox3.Enabled:=True; //X值取平均值
CheckBox4.Enabled:=True; //Y值取平均值
Label1.Enabled:=True;Edit1.Enabled:=True;//X数据点个数
Label1.Visible:=True;Edit1.Visible:=True;
Label2.Visible:=True;Edit2.Visible:=True;//Y数据点个数
Label2.Visible:=True;Edit2.Visible:=True;
Label3.Visible:=True;Edit3.Visible:=True;//X最高次幂数
Label4.Visible:=True;Edit4.Visible:=True;//Y最高次幂数
Label5.Visible:=True;Edit5.Visible:=True;//参考模拟函数
end else if F_MultiLineRegress.Variable_Num>=4 then //若选择高维坐标
begin
GroupBox1.Caption:='拟合平滑回归方法选择(高维坐标):';
RadioButton1.Enabled:=False; //最小二乘曲线(是二维)
RadioButton2.Enabled:=False; //最小二乘曲面(是三维)
RadioButton3.Enabled:=False; //切比雪夫拟合(是二维)
RadioButton4.Enabled:=False; //最佳一致逼近(是二维)
RadioButton5.Enabled:=False; //一元线性回归(是二维)
RadioButton6.Enabled:=True; //多元线性回归(是三高维)
RadioButton7.Enabled:=True; //逐步回归(三维以上)
RadioButton8.Enabled:=False; //五点三次平滑(二维)
CheckBox1.Enabled:=False; //画拟合多项式图
CheckBox2.Enabled:=False; //画参考模拟函数图
CheckBox3.Enabled:=False; //X值取平均值
CheckBox4.Enabled:=False; //Y值取平均值
Label1.Visible:=False;Edit1.Visible:=False;//X数据点个数
Label2.Visible:=False;Edit2.Visible:=False;//Y数据点个数
Label3.Visible:=False;Edit3.Visible:=False;//X最高次幂数
Label4.Visible:=False;Edit4.Visible:=False;//Y最高次幂数
Label5.Visible:=False;Edit5.Visible:=False;//参考模拟函数
end;
end;
F_AnalyseSelect.Refresh;
end;
Close;
end;
//退出
procedure TF_CoordSet.Button2Click(Sender: TObject);
begin
Close;
end;
//释放内存
procedure TF_CoordSet.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=cafree;
end;
//初始化
procedure TF_CoordSet.FormCreate(Sender: TObject);
begin
Edit1.Text:=floattostr(F_MultiLineRegress.CoordX_min);//X坐标最小值
Edit2.Text:=floattostr(F_MultiLineRegress.CoordX_max);//X坐标最大值
Edit5.Text:=floattostr(F_MultiLineRegress.CoordZ_min);//Z坐标最小值
Edit6.Text:=floattostr(F_MultiLineRegress.CoordZ_max);//Z坐标最大值
Edit7.Text:=floattostr(F_MultiLineRegress.DrawX_min);//X绘图最小值
Edit8.Text:=floattostr(F_MultiLineRegress.DrawX_max);//X绘图最大值
Edit11.Text:=floattostr(F_MultiLineRegress.DrawZ_min);//Z绘图最小值
Edit12.Text:=floattostr(F_MultiLineRegress.DrawZ_max);//Z绘图最大值
Edit13.Text:=inttostr(F_MultiLineRegress.width1);//坐标线宽
Edit14.Text:=inttostr(F_MultiLineRegress.width2);//曲线线宽
Edit15.Text:=inttostr(F_MultiLineRegress.width3);//曲线线宽
Edit20.Text:=inttostr(F_MultiLineRegress.Record_Num);//实验记录条数
if F_MultiLineRegress.Variable_Num=2 then //二维坐标
begin
Panel3.Visible:=False;
RadioButton1.Checked:=True;
Label3.Visible:=False; Edit3.Visible:=False;
Label4.Visible:=False; Edit4.Visible:=False;
Label9.Visible:=False; Edit9.Visible:=False;
Label10.Visible:=False; Edit10.Visible:=False;
Label16.Enabled:=False; Edit16.Enabled:=False;
Label17.Enabled:=False; Edit17.Enabled:=False;
Label18.Enabled:=False; Edit18.Enabled:=False;
Label5.Caption:='Y最小值:';
Label6.Caption:='Y最大值:';
Label11.Caption:='Y最小值:';
Label12.Caption:='Y最大值:';
end else if F_MultiLineRegress.Variable_Num=3 then //三维坐标
begin
Panel3.Visible:=False;
RadioButton2.Checked:=True; //立体坐标
Label3.Visible:=True; Edit3.Visible:=True;
Label4.Visible:=True; Edit4.Visible:=True;
Label9.Visible:=True; Edit9.Visible:=True;
Label10.Visible:=True; Edit10.Visible:=True;
Label16.Enabled:=True; Edit16.Enabled:=True;
Label17.Enabled:=True; Edit17.Enabled:=True;
Label18.Enabled:=True; Edit18.Enabled:=True;
Edit3.Text:=floattostr(F_MultiLineRegress.CoordY_min);//Y坐标最小值
Edit4.Text:=floattostr(F_MultiLineRegress.CoordY_max);//Y坐标最大值
Edit9.Text:=floattostr(F_MultiLineRegress.DrawY_min);//Y绘图最小值
Edit10.Text:=floattostr(F_MultiLineRegress.DrawY_max);//Y绘图最大值
Edit16.Text:=inttostr(F_MultiLineRegress.DrawX_step);//曲线线宽
Edit17.Text:=inttostr(F_MultiLineRegress.DrawY_step);
Edit18.Text:=floattostr(F_MultiLineRegress.CoordXY_Angle);//XY夹角
Label5.Caption:='Z最小值:';
Label6.Caption:='Z最大值:';
Label11.Caption:='Z最小值:';
Label12.Caption:='Z最大值:';
end else if F_MultiLineRegress.Variable_Num>=4 then //四维以上坐标
begin
RadioButton3.Checked:=True; //四维坐标
Panel3.Visible:=True;
GroupBox7.Font.Color:=clBlack;
end;
PaintBox1.Canvas.Brush.Color:=F_MultiLineRegress.Color1;//背景颜色
PaintBox2.Canvas.Brush.Color:=F_MultiLineRegress.Color2;//坐标颜色
PaintBox3.Canvas.Brush.Color:=F_MultiLineRegress.Color3;//曲线颜色
PaintBox4.Canvas.Brush.Color:=F_MultiLineRegress.Color4;//数据颜色
end;
//背景颜色
procedure TF_CoordSet.PaintBox1Click(Sender: TObject);
begin
ColorDialog1.Color:=F_MultiLineRegress.Color1;
if ColorDialog1.Execute then F_MultiLineRegress.Color1:=ColorDialog1.Color;
PaintBox1Paint(self);//调用背景颜色画板过程
end;
procedure TF_CoordSet.PaintBox1Paint(Sender: TObject);
begin
PaintBox1.Canvas.Brush.Color:=F_MultiLineRegress.Color1; //确定颜色标签颜色
PaintBox1.Canvas.Rectangle(0,0,30,20);//确定颜色标签大小
end;
//坐标颜色
procedure TF_CoordSet.PaintBox2Click(Sender: TObject);
begin
ColorDialog1.Color:=F_MultiLineRegress.Color2;
if ColorDialog1.Execute then F_MultiLineRegress.Color2:=ColorDialog1.Color;
PaintBox2Paint(self);//调用坐标颜色画板过程
end;
procedure TF_CoordSet.PaintBox2Paint(Sender: TObject);
begin
PaintBox2.Canvas.Brush.Color:=F_MultiLineRegress.Color2; //确定颜色标签颜色
PaintBox2.Canvas.Rectangle(0,0,30,20);//确定颜色标签大小
end;
//曲线颜色
procedure TF_CoordSet.PaintBox3Click(Sender: TObject);
begin
ColorDialog1.Color:=F_MultiLineRegress.Color3;
if ColorDialog1.Execute then F_MultiLineRegress.Color3:=ColorDialog1.Color;
PaintBox3Paint(self);//调用坐标颜色画板过程
end;
procedure TF_CoordSet.PaintBox3Paint(Sender: TObject);
begin
PaintBox3.Canvas.Brush.Color:=F_MultiLineRegress.Color3; //确定颜色标签颜色
PaintBox3.Canvas.Rectangle(0,0,30,20);//确定颜色标签大小
end;
//数据标识颜色
procedure TF_CoordSet.PaintBox4Click(Sender: TObject);
begin
ColorDialog1.Color:=F_MultiLineRegress.Color4;
if ColorDialog1.Execute then F_MultiLineRegress.Color4:=ColorDialog1.Color;
PaintBox4Paint(self);//调用坐标颜色画板过程
end;
procedure TF_CoordSet.PaintBox4Paint(Sender: TObject);
begin
PaintBox4.Canvas.Brush.Color:=F_MultiLineRegress.Color4; //确定颜色标签颜色
PaintBox4.Canvas.Rectangle(0,0,30,20);//确定颜色标签大小
end;
//选择二维平面坐标
procedure TF_CoordSet.RadioButton1Click(Sender: TObject);
begin
//最小二乘曲线,切比雪夫拟合,最佳一致逼近,一元线性回归,五点三次平滑
F_MultiLineRegress.Variable_Num:=2; //二维坐标
Panel3.Visible:=False;
Label3.Visible:=False; Edit3.Visible:=False;
Label4.Visible:=False; Edit4.Visible:=False;
Label9.Visible:=False; Edit9.Visible:=False;
Label10.Visible:=False; Edit10.Visible:=False;
Label16.Enabled:=False; Edit16.Enabled:=False;
Label17.Enabled:=False; Edit17.Enabled:=False;
Label18.Enabled:=False; Edit18.Enabled:=False;
Label5.Caption:='Y最小值:';
Label6.Caption:='Y最大值:';
Label11.Caption:='Y最小值:';
Label12.Caption:='Y最大值:';
F_MultiLineRegress.StrGrdChang(F_MultiLineRegress.StringGrid1); //StringGrid列变
end;
//选择三维平面坐标
procedure TF_CoordSet.RadioButton2Click(Sender: TObject);
begin
//最小二乘曲面,二元线性回归
F_MultiLineRegress.Variable_Num:=3; //三维坐标
Panel3.Visible:=False;
Label3.Visible:=True; Edit3.Visible:=True;
Label4.Visible:=True; Edit4.Visible:=True;
Label9.Visible:=True; Edit9.Visible:=True;
Label10.Visible:=True; Edit10.Visible:=True;
Label16.Enabled:=True; Edit16.Enabled:=True;
Label17.Enabled:=True; Edit17.Enabled:=True;
Label18.Enabled:=True; Edit18.Enabled:=True;
Label5.Caption:='Z最小值:';
Label6.Caption:='Z最大值:';
Label11.Caption:='Z最小值:';
Label12.Caption:='Z最大值:';
F_MultiLineRegress.StrGrdChang(F_MultiLineRegress.StringGrid1); //StringGrid列变
end;
procedure TF_CoordSet.RadioButton3Click(Sender: TObject);
begin
Panel3.Visible:=True;
end;
//高维自变量输入
procedure TF_CoordSet.Button3Click(Sender: TObject);
begin
if strtointdef(Edit19.Text,4)<4 then
begin
Edit19.Text:='';
Edit19.SetFocus;
GroupBox7.Caption:='输入数必须超过3!';
GroupBox7.Font.Color:=clRed;
end else if strtointdef(Edit19.Text,4)>=4 then
begin
F_MultiLineRegress.Variable_Num:=strtointdef(Edit19.Text,0);//四维以上坐标
F_MultiLineRegress.StrGrdChang(F_MultiLineRegress.StringGrid1); //StringGrid列变
Button1Click(Sender); //按动"确定"按钮
end;
end;
end.
从数据文件调数据(左边程序模块图,右边设计模块图)
unit U_FileDataInput;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TF_FileDataInput = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
Button1: TButton;
Button2: TButton;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
RadioButton3: TRadioButton;
Label1: TLabel;
Edit1: TEdit;
RadioButton4: TRadioButton;
procedure RadioButton4Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure RadioButton3Click(Sender: TObject);
procedure RadioButton2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure RadioButton1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
F_FileDataInput: TF_FileDataInput;
implementation
uses U_MultiLineRegress;
{$R *.dfm}
//确定
procedure TF_FileDataInput.Button1Click(Sender: TObject);
begin
F_MultiLineRegress.InputFileData;//文件调入数据子过程
end;
//退出
procedure TF_FileDataInput.Button2Click(Sender: TObject);
begin
Close;
end;
//释放内存
procedure TF_FileDataInput.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=cafree;
end;
//初始化
procedure TF_FileDataInput.FormCreate(Sender: TObject);
begin
RadioButton1Click(Sender);
end;
//调入文本数据文件
procedure TF_FileDataInput.RadioButton1Click(Sender: TObject);
begin
Edit1.Visible:=False;
Label1.Visible:=True;
end;
//调入EXCEL数据文件
procedure TF_FileDataInput.RadioButton2Click(Sender: TObject);
begin
Label1.Visible:=False;
Edit1.Visible:=True;
GroupBox2.Caption:='请输入需要打开的EXCEL数据表单名:';
Edit1.Text:='Sheet1$';
F_MultiLineRegress.SheetName:=Edit1.Text;
end;
//调入ACCESS数据文件
procedure TF_FileDataInput.RadioButton3Click(Sender: TObject);
begin
Label1.Visible:=False;
Edit1.Visible:=True;
GroupBox2.Caption:='请输入需要打开的ACCESS数据库表名:';
Edit1.Text:='金星测试数据';
F_MultiLineRegress.SheetName:=Edit1.Text;
end;
//调入SQL数据文件
procedure TF_FileDataInput.RadioButton4Click(Sender: TObject);
begin
Label1.Visible:=False;
Edit1.Visible:=True;
GroupBox2.Caption:='请输入需要打开的SQL数据库表名:';
Edit1.Text:='金星测试数据';
F_MultiLineRegress.SheetName:=Edit1.Text;
end;
end.
函数表达式线程模块
unit U_parsor;
{$F }
{$IFDEF WIN32}
{$H-}
{$ENDIF}
interface
uses SysUtils,WinTypes,WinProcs,Messages,Classes,Graphics,Controls,
Forms,Dialogs,Pars_1,Pars_2;
Type
TExpressEvaluator=function(x,y,z:extended):extended of Object;
EExpressError=Class(Exception);
{Is Raised Whenever the Expression assigned is invalid.}
//创建一个TExpress类,用于处理不同类型的函数
TExpress=Class(TComponent)
private
fparse{,done}:pparse; //
fparlist:TParString;
fvarlist:TVarString;
fparvalues:TParValues;
fExpression:string;
fTheFunction:TExpressEvaluator;
ferror:boolean;
procedure SetExpression(Expr:String);
function fdummy(x,y,z:extended):extended;
function fTheRealThing(x,y,z:extended):extended;
{Private declarations}
protected
{Protected declarations}
public
property Error:boolean read ferror;
{read the value of Error to check whether the current expression has
valid syntax}
property TheFunction:TExpressEvaluator read fThefunction;
Constructor Create(AOwner: TComponent); override;
Destructor Destroy; override;
{Call TheFunction to evaluate the current expression.Before you make
any calls to TheFunction,check that the expression has valid syntax
(->Error).If you call TheFunction for an invalid expression you get
a GPF}
procedure SetParameters(p1,p2,p3,p4,p5,p6:extended);
{Set parameter values for the available 6 parameters->SyntaxText property}
{public declarations}
published
property Expression:string read fexpression write SetExpression;
{Expression is the string to be evaluated.For syntax->SyntaxText property}
property VariableList:TVarString read fvarlist write fvarlist;
{String containing the characters for the 3 possible variables}
property ParameterList:TParString read fparlist write fparlist;
{String containing the characters for the 6 possible variables}
{published declarations}
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples',[TExpress]);
end;
//创建函数
Constructor TExpress.Create(AOwner: TComponent);
var i:integer;
begin
inherited create(AOwner);
fparse:=nil;
fvarlist:='xyz';
fparlist:='abcdef';
for i := 1 to 6 do fparvalues[i]:=1;
fExpression:='x';
fThefunction:=fdummy;
end;
//将字符串转换成函数表达式
procedure TExpress.SetExpression(Expr: ShortString);
begin
if fparse<>nil then dispose(fparse,done);
fparse:=new(pparse,init(expr,fvarlist,fparlist,ferror));
if ferror then
begin
dispose(fparse,done);
fparse:=nil;
fThefunction:=fdummy;
raise EExpressError.Create('非法语法!');//Invalid syntax
end else
begin
fparse^.setparams(fparvalues);
fExpression:=expr;
fThefunction:=fTheRealThing;
end;
end;
function TExpress.fdummy(x: Extended; y: Extended; z: Extended):extended;
begin
result:=1;
end;
function TExpress.fTheRealThing(x: Extended; y: Extended; z: Extended):extended;
begin
fparse^.f(x,y,z,result);
end;
//设置参数
procedure TExpress.SetParameters(p1: Extended; p2: Extended; p3: Extended; p4: Extended; p5: Extended; p6: Extended);
begin
if fparse<>nil then
begin
fparvalues[1]:=p1;
fparvalues[2]:=p2;
fparvalues[3]:=p3;
fparvalues[4]:=p4;
fparvalues[5]:=p5;
fparvalues[6]:=p6;
fparse^.setparams(fparvalues);
end;
end;
//销毁函数
Destructor TExpress.Destroy;
begin
if fparse<>nil then dispose(fparse,done);
inherited destroy;
end;
end.
滚动字符线程模块
unit U_RollFont;
interface
uses
Classes,Windows;
type
TRollFontThread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;
implementation
uses U_MultiLineRegress;
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure TRollFontThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }
{ TRollFontThread }
procedure TRollFontThread.Execute;
begin
{ Place thread code here }
while 1>0 do
begin
F_MultiLineRegress.Label100.Caption:='《拟合回归平滑分析》是一个通用性较强的利用电脑处理'
'数据拟合模拟专用软件。该软件采用多元线性回归、指定函数拟合等模拟'
'方法,可以算出适合实验数据的最近函数关系,并将该函数关系以平面或'
'立体图形显示出来,供研究人员分析对比。《拟合回归平滑分析》软件可'
'以通过手工输入方式接受实验数据,也可以通过调用数据文件方式直接接'
'实验数据,接受的数据文件可以是文本,EXCEL,ACCESS,SQL和ORAClE等数'
'据。软件算法精确,处理性能良好,速度较快,也可处理大型实验数据。';
F_MultiLineRegress.Label100.Left:=F_MultiLineRegress.Label100.Left-1;
if (F_MultiLineRegress.Label100.Left=-F_MultiLineRegress.Label100.Width) then
begin
F_MultiLineRegress.Label100.Left:=F_MultiLineRegress.Panel2.Width-20;
end;
Sleep(30);
end;
end;
end.
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。