在带约束的 MATLAB 中使用向量的线性组合拟合数据

Fitting Data with Linear Combination of Vectors in MATLAB with Constraints

在 MATLAB 中工作。我有以下等式:

S = aW + bX + cY + dZ

其中 S、W、X、Y 和 Z 都是已知的 n x 1 向量。我正在尝试使用基向量 W、X、Y 和 Z 的线性组合来拟合 S 的数据,并在常数 (a、b、c、d) 大于 0 的情况下进行约束。我设法做到了这在 Excel 的求解器中,并试图在 MATLAB 上解决,针对 fmincon 之类的函数,但我对 MATLAB 并不过分熟悉并且觉得我是误解 fmincon.

的使用

我正在寻求帮助以了解 fmincon 对我的问题的使用,或重定向到更有效的解决方法。

目前我有:

initials = [0.2 0.2 0.2 0.2];
fun = @(x)x(1)*W + x(2)*X + x(3)*Y + x(4)*Z;
lb = [0,0,0,0];
soln = fmincon(fun,initials,data,b,Aeq,beq,lb,ub);

我收到一条错误消息,指出“A 必须有 4 列”。其中 A 指的是我的变量数据,它对应于上面等式中的 S。我不明白为什么它需要 4 列。还要注意我上面的代码片段中未明确定义的变量被定义为 [],作为 space 持有者。

您尝试做的与我在 中给出的答案相似。

该过程与您在 EXCEL 中使用求解器所做的类似。您创建一个 objective 函数,它将 (a, b, c, d) 作为输入参数并输出拟合度 (mse),然后使用 fmincon 或类似的求解器来获得最佳 (a, b, c , d) 最小化这个 mse。请参阅下面的代码(没有 MATLAB 对其进行测试,但它应该可以工作)。

function [a, b, c, d] = optimize_abcd(W, X, Y, Z)
%=========================================================
%Second argument is the starting point, second to the last argument is the lower bound 
%to ensure the solutions are all positive
res = fmincon(@MSE, [0,0,0,0], [], [], [], [], [0,0,0,0], []);
a=res(1);
b=res(2);
c=res(3);
d=res(4);

    function mse = MSE(x_)
        a_=x_(1);
        b_=x_(2);
        c_=x_(3);
        d_=x_(4);
        S_ = a_*W + b_*X + c_*Y + d_*Z
        mse = norm(S_-S);
    end
end

在这种情况下使用 fmincon 是一个巨大的矫枉过正。这就像使用大而重的显微镜来破解坚果......或火星漫游者拖着手推车或......无论如何:)如果你不必处理大量的矢量可能没关系。如果您需要拟合数十万个此类向量,则可能需要数小时。但是这个经典方案会快几个数量级。

%first make a n x 4 matrix of your vectors;
P=[W,X,Y,Z];
% now your equation looks like this S = P*m where m is 4 x 1 vectro
% containing your coefficients ( m = [a,b,c,d] )
% so solution will be simply
m_1 = inv(P'*P)*P'*S;
% or you can use this form
m_2 = (P'*P)\P'*S;
% or even simpler
m_3 = (S'/P')';
% all three solutions should give exactly same resul
% third solution is the neatest but may not work in every version of matlab

% Your modeled vector will be
Sm = P*m_3; %you can use any of m_1, m_2 or m_3;
% And your residual 
R = S-Sm;

如果您需要处理许多向量,请不要使用 for 循环。 For 循环在 Matlab 中非常慢,如果可能,您应该改用矩阵。 S 也可以是 nk 矩阵,其中 k 是您要处理的数字向量。在这种情况下,m 将是 4k 矩阵。