声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 6358|回复: 30

[编程技巧] [求助]:利用非线性最小二乘法来优化参数的问题?

[复制链接]
发表于 2006-11-16 14:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
各位高手,我修改了一下我的程序,可以运行,但是拟合出来的数据不对,不知道是何缘故?
可运行的程序如下:
首先编制非线性模型m文件(sta67_2m.m:
function dd1=model(beta0,dd2)
a=beta0(1);
b=beta0(2);
c=beta0(3);
d=beta0(4);
e=beta0(5);
f=beta0(6);
g=beta0(7);
h=beta0(8);
k=beta0(9);
l=beta0(10);
dd1=a*sin(2*pi*0.97656*dd2+b)+c*sin(2*pi*1.9531*dd2+d)+e*sin(2*pi*2.9297*dd2+f)+g*sin(2*pi*3.9063*dd2+h)+k*sin(2*pi*4.8828*dd2+l);

然后在命令栏里面输入:
yy=Data(2100*500:2103*500);dd1=yy';
x=0:0.002:3;dd2=x;
beta0=[0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5];
nlintool(dd2,dd1,'sta67_2m',beta0);
betafit=nlinfit(dd2,dd1,'sta67_2m',beta0);

betafit=0.039909             -35.47
             -0.044785              0.075721
             -0.13027              0.8733
              0.32827              11.404
             0.40317        -4.0571
然后我将实际dd1值的图形和拟合出来的dd1的图形进行对比(见附图1和附图2),从两图可以看出可以看出图形形状不一样且大小也差的很远,不知道这是怎么回事?

实际dd1图形

实际dd1图形

拟合dd1图形

拟合dd1图形
回复
分享到:

使用道具 举报

发表于 2006-11-16 14:47 | 显示全部楼层

回复

拟合不同于插值, 有一定偏差一般是很正常的.
另:你也可以试试lsqcurvefit函数.

[ 本帖最后由 xjzuo 于 2006-11-16 14:52 编辑 ]

评分

1

查看全部评分

 楼主| 发表于 2006-11-16 15:00 | 显示全部楼层
lsqcurvefit函数如何使用呀?能否告知?我这里有10个参数要识别,lsqcurvefit命令能否识别的出来?
发表于 2006-11-17 08:20 | 显示全部楼层
原帖由 kingsword1979 于 2006-11-16 15:00 发表
lsqcurvefit函数如何使用呀?能否告知?我这里有10个参数要识别,lsqcurvefit命令能否识别的出来?



doc lsqcurvefit看一下帮助吧,里边有详细的说明

还有例子
 楼主| 发表于 2006-11-17 10:06 | 显示全部楼层
谢谢楼上的高手
 楼主| 发表于 2006-11-18 16:24 | 显示全部楼层
楼上的高手,我借了本书看到这样一个例子,很符合我的需要,但是我原搬不动的把书上的例子抄下来,在MATLAB里面运行,还是出错,请帮我看看,谢谢。
例子如下:函数为:y=c(1)*exp(-d(1)*x)+c(2)*exp(-d(2)*x)
function F=myfun(d,Data)
%假设y=c(1)*exp(-d(1)*x)+...+c(n))*exp(-d(n)*x)
%带有n个线性参数,n个非线性参数
x=Data(:,1);y=Data(:,2);
A=zeros(length(x),length(d));
for i=1:length(d)
    A(:,i)=exp(-d(i)*x);
end
c=A\y;      %通过A*c=y求解线性参数c;
z=A*c;
f=z-y;

Data=[0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0;5.8955,3.5639,2.5173,1.9799,1.899,1.3938,1.1359,1.0096,1.0343,0.8435,0.6856,0.61,0.5392,0.3946,0.3903,0.5474,0.3459,0.137,0.2211,0.1704,0.2636]';
options=optimset('LargeScale','off');
options=optimset(options,'MaxFunEvals',300);
options=optimset(options,'LevenbergMarquardt','off');
options=optimset(options,'LineSearch','cubicpoly');

d0=[1,2];
d=lsqnonlin('myfun2',d0,[],[],options,Data);

【结果输出】
c=2.8898
     3.0061
d=1.4006    10.5891
我运行了上面的例子,怎么老是出错,不知道能不能告诉我问题出在哪里?谢谢!
发表于 2006-11-18 16:31 | 显示全部楼层
  1. function F=myfun(d,Data)
  2. %假设y=c(1)*exp(-d(1)*x)+...+c(n))*exp(-d(n)*x)
  3. %带有n个线性参数,n个非线性参数
  4. x=Data(:,1);y=Data(:,2);
  5. A=zeros(length(x),length(d));
  6. for i=1:length(d)
  7.     A(:,i)=exp(-d(i)*x);
  8. end
  9. c=A\y;      %通过A*c=y求解线性参数c;
  10. z=A*c;
  11. F=z-y;
复制代码


上面部分存成myfun.m,你的代码中F写成了f,matlab是区分大小写的

  1. Data=[0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0;5.8955,3.5639,2.5173,1.9799,1.899,1.3938,1.1359,1.0096,1.0343,0.8435,0.6856,0.61,0.5392,0.3946,0.3903,0.5474,0.3459,0.137,0.2211,0.1704,0.2636]';
  2. options=optimset('LargeScale','off');
  3. options=optimset(options,'MaxFunEvals',300);
  4. options=optimset(options,'LevenbergMarquardt','off');
  5. options=optimset(options,'LineSearch','cubicpoly');

  6. d0=[1,2];
  7. d=lsqnonlin('myfun',d0,[],[],options,Data)
复制代码


注意函数名
 楼主| 发表于 2006-11-18 21:29 | 显示全部楼层
非常感谢楼上的高手帮我指出错误,谢谢!更正程序后,出现这样的提示:
Optimization terminated: directional derivative along
search direction less than TolFun and infinity-norm of
gradient less than 10*(TolFun+TolX).

这怎么解决呢?
 楼主| 发表于 2006-11-18 21:32 | 显示全部楼层
d是非线性项的参数,可以正确识别出来,但是c是线性项的参数,程序没有计算出来,是不是跟上面的提示有关,如何更正呢?
发表于 2006-11-19 10:00 | 显示全部楼层

回复

你把你原来的数据文件传上来吧.这样我们可以试试哪个函数能拟合的好一些.
 楼主| 发表于 2006-11-19 10:12 | 显示全部楼层
y的文件数据在附件1,另外x的文件数据就是时间x=0:0.002:3,谢谢帮我分析一下。
 楼主| 发表于 2006-11-19 10:40 | 显示全部楼层
上面的例子我已经可以正确求出参数c和d了,现在我根据上面的例子来模仿编程,程序如下:
首先编制m.文件(文件名为myfun.m)
function F=myfun(d,Data)
%假设y=c(1)*sin(2*pi*0.97656*t+d(1))+c(2)*sin(2*pi*1.9531*t+d(2))+c(3)*sin(2*pi*2.9297*t+d(3))+c(4)*sin(2*pi*3.9063*t+d(4))+c(5)*sin(2*pi*4.8828*t+d(5))
%带有5个线性参数c,5个非线性参数d
t=0:0.002:3;x=t';
y=Data(2100*500:2103*500);
A=zeros(length(x),length(d));
for i=1:length(d))
    A(:,i)=sin(2*pi*i*0.97656*x+d(i));
end
c=A\y;
z=A*c;
F=z-y;

然后输入上面附件里面的数据Data文件
options=optimset('LargeScale','off');
options=optimset(options,'MaxFunEvals',300);
options=optimset(options,'LevenbergMarquardt','off');
%options=optimset(options,'LineSearch','cubicpoly');
d0=[1,2,3,4,5];
d=lsqnonlin('myfun',d0,[],[],options,Data);
结果Matlab提示:
??? Error using ==> optim\private\lsqncommon
User supplied function failed with the following error:

Error: File: d:\MATLAB7\work\myfun.m Line: 7 Column: 18
Unbalanced or misused parentheses or brackets.

Error in ==> lsqnonlin at 147
[x,Resnorm,FVAL,EXITFLAG,OUTPUT,LAMBDA,JACOB] = ...

这是什么原因呢?哪位高手能帮我改通顺吗?

[ 本帖最后由 kingsword1979 于 2006-11-19 10:51 编辑 ]
发表于 2006-11-19 16:10 | 显示全部楼层
怎么数据好象不可用?
 楼主| 发表于 2006-11-19 22:55 | 显示全部楼层
我用的是Matlab7
发表于 2006-11-19 23:21 | 显示全部楼层

回复

先写成.xls或.txt,再传一下吧.我一直用的是6.5。
但数据可能已经corrupt. 应该不是版本的问题.
另:我认为你也许把问题复杂化了,参数不必象你那样进行区分.

[ 本帖最后由 xjzuo 于 2006-11-19 23:24 编辑 ]
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-5-19 16:18 , Processed in 0.081518 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表