首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >最小二乘曲面拟合的第一性原理

最小二乘曲面拟合的第一性原理
EN

Stack Overflow用户
提问于 2016-02-29 14:57:42
回答 1查看 159关注 0票数 1

我想让这“手工”,而不是使用表面拟合工具,因为根据我的数据,表面拟合可能有所不同。所以,我首先在excel表格中读取数据,然后初始化一些系数,计算一个三维曲面(f(x,y)),然后计算最小二乘和,这是我想要最小化的。每次运行脚本时,它都会告诉我,即使当我更改初始值时,我也处于本地最小值。改变容忍度也不会影响结果。

这是代码:

代码语言:javascript
复制
% flow function in a separate .m file (approximation, it’s a negative paraboloid, maybe if required, this function may vary):

function Q = flow(P1,P2,a,b,c,d,e,f)
Q1 = a-b.*P1-c.*P1.^2;
Q2 = d-e.*P2-f.*P2.^2;
Q = Q1 + Q2;

% Variable read, I use a xlsread instead
p1a = [-5, -5, -5, -5, -5, -5, -5, -5, -5, -5];
p2a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
qa = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];

p1b = [-6, -6, -6, -6, -6, -6, -6, -6, -6, -6];
p2b = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
qb = [12, 11, 10, 9, 8, 7, 6, 5, 4, 3];

% Variable initialization
coef = [50, 1, 1, 10, 1, 1];

% Function calculation
q1a = flow(p1a,p2a,coef(1),coef(2),coef(3),coef(4),coef(5),coef(6)); 
q1b = flow(p1b,p2b,coef(1),coef(2),coef(3),coef(4),coef(5),coef(6));

% Least squares
LQa = (qa-q1a).^2;
LQb = (qb-q1b).^2;
Sa = sum(LQa);
Sb = sum(LQb);
St = Sa+Sb;

% Optimization (minimize the least squares sum)
func = @(coef)(St);
init = coef;
opt = optimoptions('fminunc', 'Algorithm', 'quasi-newton', 'Display', 'iter','TolX', 1e-35, 'TolFun', 1e-30);
[coefmin, Stmin] = fminunc(func, init, opt);

如果您运行此操作,您应该得到15546Stmin结果,但是如果您更改了系数,您将得到另一个结果,它也将被认为是一个局部最小值。

我做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-01 07:23:19

问题是您的func只是一个常数。它只是返回一个预先计算过的值,St,它是常数,不管您传递给func的是什么输入。尝试用各种不同的输入调用func来测试这一点。

你的目标函数需要包含把你带到St的所有计算。因此,我建议您将func替换为保存在m文件中的函数,如下所示:

代码语言:javascript
复制
function St = objectiveFunction(coef, p1a, p2a, p1b, p2b, qa, qb, q1a, q1b)

    % Function calculation
    q1a = flow(p1a,p2a,coef(1),coef(2),coef(3),coef(4),coef(5),coef(6)); 
    q1b = flow(p1b,p2b,coef(1),coef(2),coef(3),coef(4),coef(5),coef(6));

    % Least squares
    LQa = (qa-q1a).^2;
    LQb = (qb-q1b).^2;
    Sa = sum(LQa);
    Sb = sum(LQb);
    St = Sa+Sb;

end

然后在脚本中使用这样的匿名函数调用objectiveFunction

代码语言:javascript
复制
[coefmin, Stmin] = fminunc(@(coef)(objectiveFunction(coef, p1a, p2a, p1b, p2b, qa, qb, q1a, q1b)), init, opt);

其思想是创建一个只接受单个参数coef的匿名函数,这是fminunc将调用并传递回目标函数的变量。您的objectiveFunction需要的其他参数(即p1a, p2a, p1b,...)现在被认为是由匿名函数预先计算的,因此也是由fminunc计算出来的。

剩下的代码可以保持不变。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35702704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档