📄 parafac2.m
字号:
Delta=5;
else
Delta=max(2,Delta);
end
dA=A-Ao;
dB=B-Bo;
dC=C-Co;
Fit1=sum(sum(abs(X-A*ppp(B,C).').^2));
regx=[1 0 0 Fit1];
Fit2=sum(sum(abs(X-(A+Delta*dA)*ppp((B+Delta*dB),(C+Delta*dC)).').^2));
regx=[regx;1 Delta Delta.^2 Fit2];
while Fit2>Fit1
if dbg
disp('while Fit2>Fit1')
end
Delta=Delta*.6;
Fit2=sum(sum(abs(X-(A+Delta*dA)*ppp((B+Delta*dB),(C+Delta*dC)).').^2));
regx=[regx;1 Delta Delta.^2 Fit2];
end
Fit3=sum(sum(abs(X-(A+2*Delta*dA)*ppp((B+2*Delta*dB),(C+2*Delta*dC)).').^2));
regx=[regx;1 2*Delta (2*Delta).^2 Fit3];
while Fit3<Fit2
if dbg
disp('while Fit3<Fit2')
end
Delta=1.8*Delta;
Fit2=Fit3;
Fit3=sum(sum(abs(X-(A+2*Delta*dA)*ppp((B+2*Delta*dB),(C+2*Delta*dC)).').^2));
regx=[regx;1 2*Delta (2*Delta).^2 Fit2];
end
% Add one point between the two smallest fits
[a,b]=sort(regx(:,4));
regx=regx(b,:);
Delta4=(regx(1,2)+regx(2,2))/2;
Fit4=sum(sum(abs(X-(A+Delta4*dA)*ppp((B+Delta4*dB),(C+Delta4*dC)).').^2));
regx=[regx;1 Delta4 Delta4.^2 Fit4];
%reg=pinv([1 0 0;1 Delta Delta^2;1 2*Delta (2*Delta)^2])*[Fit1;Fit2;Fit3]
reg=pinv(regx(:,1:3))*regx(:,4);
%DeltaMin=2*reg(3);
DeltaMin=-reg(2)/(2*reg(3));
%a*x2 + bx + c = fit
%2ax + b = 0
%x=-b/2a
NewA=A+DeltaMin*dA;
NewB=B+DeltaMin*dB;
NewC=C+DeltaMin*dC;
Fit=sum(sum(abs(X-NewA*ppp(NewB,NewC).').^2));
if dbg
regx
plot(regx(:,2),regx(:,4),'o'),
hold on
x=linspace(0,max(regx(:,2))*1.2);
plot(x',[ones(100,1) x' x'.^2]*reg),
hold off
drawnow
[DeltaMin Fit],pause
end
[minfit,number]=min(regx(:,4));
if Fit>minfit
DeltaMin=regx(number,2);
NewA=A+DeltaMin*dA;
NewB=B+DeltaMin*dB;
NewC=C+DeltaMin*dC;
end
function AB=ppp(A,B);
% $ Version 1.02 $ Date 28. July 1998 $ Not compiled $
%
% Copyright, 1998 -
% This M-file and the code in it belongs to the holder of the
% copyrights and is made public under the following constraints:
% It must not be changed or modified and code cannot be added.
% The file must be regarded as read-only. Furthermore, the
% code can not be made part of anything but the 'N-way Toolbox'.
% In case of doubt, contact the holder of the copyrights.
%
% Rasmus Bro
% Chemometrics Group, Food Technology
% Department of Food and Dairy Science
% Royal Veterinary and Agricultutal University
% Rolighedsvej 30, DK-1958 Frederiksberg, Denmark
% Phone +45 35283296
% Fax +45 35283245
% E-mail rb@kvl.dk
%
% The parallel proportional profiles product - triple-P product
% For two matrices with similar column dimension the triple-P product
% is ppp(A,B) = [kron(B(:,1),A(:,1) .... kron(B(:,F),A(:,F)]
%
% AB = ppp(A,B);
%
% Copyright 1998
% Rasmus Bro
% KVL,DK
% rb@kvl.dk
[I,F]=size(A);
[J,F1]=size(B);
if F~=F1
error(' Error in ppp.m - The matrices must have the same number of columns')
end
AB=zeros(I*J,F);
for f=1:F
ab=A(:,f)*B(:,f).';
AB(:,f)=ab(:);
end
function [x,w] = fastnnls(XtX,Xty,tol)
%NNLS Non-negative least-squares.
% b = fastnnls(XtX,Xty) returns the vector b that solves X*b = y
% in a least squares sense, subject to b >= 0, given the inputs
% XtX = X'*X and Xty = X'*y.
%
% A default tolerance of TOL = MAX(SIZE(X)) * NORM(X,1) * EPS
% is used for deciding when elements of b are less than zero.
% This can be overridden with b = fastnnls(X,y,TOL).
%
% [b,w] = fastnnls(XtX,Xty) also returns dual vector w where
% w(i) < 0 where b(i) = 0 and w(i) = 0 where b(i) > 0.
%
% See also LSCOV, SLASH.
% L. Shure 5-8-87
% Revised, 12-15-88,8-31-89 LS.
% Copyright (c) 1984-94 by The MathWorks, Inc.
% Revised by:
% Copyright
% Rasmus Bro 1995
% Denmark
% E-mail rb@kvl.dk
% According to Bro & de Jong, J. Chemom, 1997
% initialize variables
if nargin < 3
tol = 10*eps*norm(XtX,1)*max(size(XtX));
end
[m,n] = size(XtX);
P = zeros(1,n);
Z = 1:n;
x = P';
ZZ=Z;
w = Xty-XtX*x;
% set up iteration criterion
iter = 0;
itmax = 30*n;
% outer loop to put variables into set to hold positive coefficients
while any(Z) & any(w(ZZ) > tol)
[wt,t] = max(w(ZZ));
t = ZZ(t);
P(1,t) = t;
Z(t) = 0;
PP = find(P);
ZZ = find(Z);
nzz = size(ZZ);
z(PP')=(Xty(PP)'/XtX(PP,PP)');
z(ZZ) = zeros(nzz(2),nzz(1))';
z=z(:);
% inner loop to remove elements from the positive set which no longer belong
while any((z(PP) <= tol)) & iter < itmax
iter = iter + 1;
QQ = find((z <= tol) & P');
alpha = min(x(QQ)./(x(QQ) - z(QQ)));
x = x + alpha*(z - x);
ij = find(abs(x) < tol & P' ~= 0);
Z(ij)=ij';
P(ij)=zeros(1,max(size(ij)));
PP = find(P);
ZZ = find(Z);
nzz = size(ZZ);
z(PP)=(Xty(PP)'/XtX(PP,PP)');
z(ZZ) = zeros(nzz(2),nzz(1));
z=z(:);
end
x = z;
w = Xty-XtX*x;
end
x=x(:);
function B=unimodalcrossproducts(XtX,XtY,Bold)
% Solves the problem min|Y-XB'| subject to the columns of
% B are unimodal and nonnegative. The algorithm is iterative and
% only one iteration is given, hence the solution is only improving
% the current estimate
%
% I/O B=unimodalcrossproducts(XtX,XtY,Bold)
% Modified from unimodal.m to handle crossproducts in input 1999
%
% Copyright 1997
%
% Rasmus Bro
% Royal Veterinary & Agricultural University
% Denmark
% rb@kvl.dk
%
% Reference
% Bro and Sidiropoulos, "Journal of Chemometrics", 1998, 12, 223-247.
B=Bold;
F=size(B,2);
for f=1:F
xty = XtY(f,:)-XtX(f,[1:f-1 f+1:F])*B(:,[1:f-1 f+1:F])';
beta=pinv(XtX(f,f))*xty;
B(:,f)=ulsr(beta',1);
end
function [b,All,MaxML]=ulsr(x,NonNeg);
% ------INPUT------
%
% x is the vector to be approximated
% NonNeg If NonNeg is one, nonnegativity is imposed
%
%
%
% ------OUTPUT-----
%
% b is the best ULSR vector
% All is containing in its i'th column the ULSRFIX solution for mode
% location at the i'th element. The ULSR solution given in All
% is found disregarding the i'th element and hence NOT optimal
% MaxML is the optimal (leftmost) mode location (i.e. position of maximum)
%
% ___________________________________________________________
%
%
% Copyright 1997
%
% Nikos Sidiroupolos
% University of Maryland
% Maryland, US
%
% &
%
% Rasmus Bro
% Royal Veterinary & Agricultural University
% Denmark
%
%
% ___________________________________________________________
% This file uses MONREG.M
x=x(:);
I=length(x);
xmin=min(x);
if xmin<0
x=x-xmin;
end
% THE SUBSEQUENT
% CALCULATES BEST BY TWO MONOTONIC REGRESSIONS
% B1(1:i,i) contains the monontonic increasing regr. on x(1:i)
[b1,out,B1]=monreg(x);
% BI is the opposite of B1. Hence BI(i:I,i) holds the monotonic
% decreasing regression on x(i:I)
[bI,out,BI]=monreg(flipud(x));
BI=flipud(fliplr(BI));
% Together B1 and BI can be concatenated to give the solution to
% problem ULSR for any modloc position AS long as we do not pay
% attention to the element of x at this position
All=zeros(I,I+2);
All(1:I,3:I+2)=B1;
All(1:I,1:I)=All(1:I,1:I)+BI;
All=All(:,2:I+1);
Allmin=All;
Allmax=All;
% All(:,i) holds the ULSR solution for modloc = i, disregarding x(i),
iii=find(x>=max(All)');
b=All(:,iii(1));
b(iii(1))=x(iii(1));
Bestfit=sum((b-x).^2);
MaxML=iii(1);
for ii=2:length(iii)
this=All(:,iii(ii));
this(iii(ii))=x(iii(ii));
thisfit=sum((this-x).^2);
if thisfit<Bestfit
b=this;
Bestfit=thisfit;
MaxML=iii(ii);
end
end
if xmin<0
b=b+xmin;
end
% Impose nonnegativity
if NonNeg==1
if any(b<0)
id=find(b<0);
% Note that changing the negative values to zero does not affect the
% solution with respect to nonnegative parameters and position of the
% maximum.
b(id)=zeros(size(id))+0;
end
end
function [b,B,AllBs]=monreg(x);
% Monotonic regression according
% to J. B. Kruskal 64
%
% b = min|x-b| subject to monotonic increase
% B = b, but condensed
% AllBs = All monotonic regressions, i.e. AllBs(1:i,i) is the
% monotonic regression of x(1:i)
%
%
% Copyright 1997
%
% Rasmus Bro
% Royal Veterinary & Agricultural University
% Denmark
% rb@kvl.dk
%
I=length(x);
if size(x,2)==2
B=x;
else
B=[x(:) ones(I,1)];
end
AllBs=zeros(I,I);
AllBs(1,1)=x(1);
i=1;
while i<size(B,1)
if B(i,1)>B(min(I,i+1),1)
summ=B(i,2)+B(i+1,2);
B=[B(1:i-1,:);[(B(i,1)*B(i,2)+B(i+1,1)*B(i+1,2))/(summ) summ];B(i+2:size(B,1),:)];
OK=1;
while OK
if B(i,1)<B(max(1,i-1),1)
summ=B(i,2)+B(i-1,2);
B=[B(1:i-2,:);[(B(i,1)*B(i,2)+B(i-1,1)*B(i-1,2))/(summ) summ];B(i+1:size(B,1),:)];
i=max(1,i-1);
else
OK=0;
end
end
bInterim=[];
for i2=1:i
bInterim=[bInterim;zeros(B(i2,2),1)+B(i2,1)];
end
No=sum(B(1:i,2));
AllBs(1:No,No)=bInterim;
else
i=i+1;
bInterim=[];
for i2=1:i
bInterim=[bInterim;zeros(B(i2,2),1)+B(i2,1)];
end
No=sum(B(1:i,2));
AllBs(1:No,No)=bInterim;
end
end
b=[];
for i=1:size(B,1)
b=[b;zeros(B(i,2),1)+B(i,1)];
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -