Create least squares fit for linear combinations
7 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Hi, I'm trying to create an unmixing alogirthm and want help in doing so.
To start off, I have 2 values (let's say x1 and x2) that make up an unknown (let's say y1). I'm trying to figure out what combination of these values make up the unknown, so the equation would be:
y1 = (a1 * x1) + (a2 * x2)
where a1 + a2 = 1, as they're percentages of each x value.
I'm trying to understand how to create a function that would find a value of a1 and a2 to minimize the difference between the unknown and the combination. In essence, I'm trying to minimize using the least squares fit:
y1 - (a1*x1) + (a2*x2)
Any help would be appreciated, thanks!
1 comentario
Respuestas (3)
Bruno Luong
el 13 de Abr. de 2022
first write
a2 = 1 - a1
replace in the first equation with y, solve for a1, then a2
0 comentarios
Matt J
el 15 de Abr. de 2022
I'm assuming x1,x2, and y1 are all equal-sized column vectors.
LHS=x1(:)-x2(:);
RHS=y1(:)-x2(:);
a1=min(max(LHS\RHS,0),1);
a2=1-a1;
a=[a1,a2];
9 comentarios
Matt J
el 17 de Abr. de 2022
Editada: Matt J
el 17 de Abr. de 2022
x1=zeros(1,1000);
x2=ones(1,1000);
y=0.1*x1+0.9*x2;
x1=x1+0.2*randn(size(x1));
x2=x2+0.2*randn(size(x2));
y=y+0.02*randn(size(y));
dx = x1-x2;
dxy = y-x2;
% leastsquare
a1=dot(dxy,dx)./dot(dx,dx)
% total least-square
[~,~,V] = svd([dx(:) dxy(:)], 0); % find the SVD of Z.
a1 = -V(1,2) / V(2,2)
%total least square constrained
C=[x1(:),x2(:),-y(:)];
d=zeros(size(C,1),1);
a=lsqlin(C,d,[],[], [1,1,-1],0,[0;0;0]);
a=a(1:2)/a(3);
a(1)
Bruno Luong
el 17 de Abr. de 2022
Better but I don't think what you call lsqlin is Total Least squares according to Wikipedia, where the Frobenius norm of the augmented error matrix
% norm([E F],'fro')
is minimize, not
% norm(C*aa,2)
Your solution and mine clearly differ if you run smaller numerical example.
x1=zeros(1,10);
x2=ones(1,10);
y=0.1*x1+0.9*x2;
x1=x1+0.1*randn(size(x1));
x2=x2+0.1*randn(size(x2));
y=y+0.01*randn(size(y));
dx = x1-x2;
dxy = y-x2;
% leastsquare
a1=dot(dxy,dx)./dot(dx,dx)
% total least-square
[~,~,V] = svd([dx(:) dxy(:)], 0); % find the SVD of Z.
a1 = -V(1,2) / V(2,2)
%total least square constrained
C=[x1(:),x2(:),-y(:)];
d=zeros(size(C,1),1);
a=lsqlin(C,d,[],[], [1,1,-1],0,[0;0;0]);
a=a(1:2)/a(3)
Bruno Luong
el 17 de Abr. de 2022
Editada: Bruno Luong
el 17 de Abr. de 2022
I also make a flawed code of total leat squares earlier (under comment of Matt's answer), since dx and dxy are correlated so my TLSQ implement on those vectors is not the appropriate. The better implementation is
n=1000;
x1=zeros(1,n);
x2=ones(1,n);
y=0.1*x1+0.9*x2;
x1=x1+0.1*randn(size(x1));
x2=x2+0.1*randn(size(x2));
y=y+0.1*randn(size(y));
% total least-square
% assuming ccov([x1(:) x2(:) y(:)]) is sigma*eye(3)
v = (y+x1-2*x2)/sqrt(6);
w = (y-x1)/sqrt(2);
[~,~,V] = svd([v(:) w(:)], 0);
V22 = V(2,2)*sqrt(6);
V12 = V(1,2)*sqrt(2);
a1 = (V22-V12)/(V22+V12);
a1 = min(max(a1,0),1);
a2 = 1-a1;
a = [a1; a2]
1 comentario
Bruno Luong
el 17 de Abr. de 2022
Doing some montecarlo to evaluate the precision of each method (script attached). LSQ and LSQLIN seems to have some systematic errors (bias).

Ver también
Categorías
Más información sobre Linear Least Squares en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!