📄 jkparafac.m
字号:
% $ Version 1.02 $ Date 28. July 1998 $ Not compiled $
% $ Version 2.00 $ May 2001 $ Changed to array notation $ RB $ Not compiled $
[I,F]=size(A);
[J,F1]=size(B);
if F~=F1
error(' Error in kr.m - The matrices must have the same number of columns')
end
AB=zeros(I*J,F);
for f=1:F
ab=B(:,f)*A(:,f).';
AB(:,f)=ab(:);
end
function load=pfls(ZtZ,ZtX,dimX,cons,OldLoad,DoWeight,W);
%PFLS
%
% See also:
% 'unimodal' 'monreg' 'fastnnls'
%
%
% Calculate the least squares estimate of
% load in the model X=load*Z' => X' = Z*load'
% given ZtZ and ZtX
% cons defines if an unconstrained solution is estimated (0)
% or an orthogonal (1), a nonnegativity (2), or a unimodality (3)
%
%
% Used by PARAFAC.M
% $ 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
%
% Apr 2002 - Fixed error in weighted ls $ rb
if ~DoWeight
if cons==0 % No constr
%load=((Z'*Z)\Z'*Xinuse)';
load=(pinv(ZtZ)*ZtX)';
elseif cons==1 % Orthogonal loadings acc. to Harshman & Lundy 94
load=ZtX'*(ZtX*ZtX')^(-.5);
elseif cons==2 % Nonnegativity constraint
load=zeros(size(OldLoad));
for i=1:dimX
load(i,:)=fastnnls(ZtZ,ZtX(:,i))';
% if min(load(i,:))<-eps*1000
% load(i,:)=OldLoad(i,:);
% end
end
elseif cons==3 % Unimodality & NNLS
load=OldLoad;
F=size(OldLoad,2);
if F>1
for i=1:F
ztz=ZtZ(i,i);
ztX=ZtX(i,:)-ZtZ(i,[1:i-1 i+1:F])*load(:,[1:i-1 i+1:F])';
beta=(pinv(ztz)*ztX)';
load(:,i)=ulsr(beta,1);
end
else
beta=(pinv(ZtZ)*ZtX)';
load=ulsr(beta,1);
end
end
elseif DoWeight
Z=ZtZ;
X=ZtX;
if cons==0 % No constr
load=OldLoad;
one=ones(1,size(Z,2));
for i=1:dimX
ZW=Z.*(W(i,:).^2'*one);
%load(i,:)=(pinv(Z'*diag(W(i,:))*Z)*(Z'*diag(W(i,:))*X(i,:)'))';
load(i,:)=(pinv(ZW'*Z)*(ZW'*X(i,:)'))';
end
elseif cons==2 % Nonnegativity constraint
load=OldLoad;
one=ones(1,size(Z,2));
for i=1:dimX
ZW=Z.*(W(i,:).^2'*one);
load(i,:)=fastnnls(ZW'*Z,ZW'*X(i,:)')';
end
elseif cons==1
disp(' Weighted orthogonality not implemented yet')
disp(' Please contact the authors for further information')
error
elseif cons==3
disp(' Weighted unimodality not implemented yet')
disp(' Please contact the authors for further information')
error
end
end
% Check that NNLS and alike do not intermediately produce columns of only zeros
if cons==2|cons==3
if any(sum(load)==0) % If a column becomes only zeros the algorithm gets instable, hence the estimate is weighted with the prior estimate. This should circumvent numerical problems during the iterations
load = .9*load+.1*OldLoad;
end
end
function [Xm]=nmodel(Factors,G,Om);
%NMODEL make model of data from loadings
%
% function [Xm]=nmodel(Factors,G,Om);
%
% This algorithm requires access to:
% 'neye.m'
%
%
% [Xm]=nmodel(Factors,G,Om);
%
% Factors : The factors in a cell array. Use any factors from
% any model.
% G : The core array. If 'G' is not defined it is assumed
% that a PARAFAC model is being established.
% Use G = [] in the PARAFAC case.
% Om : Oblique mode.
% 'Om'=[] or 'Om'=0, means that orthogonal
% projections are requsted. (default)
% 'Om'=1 means that the factors are oblique.
% 'Om'=2 means that the ortho/oblique is solved automatically.
% This takes a little additional time.
% Xm : The model of X.
%
% Using the factors as they are (and the core, if defined) the general N-way model
% is calculated.
% $ Version 2.00 $ May 2001 $ Changed to array notation $ RB $ Not compiled $
% $ Version 1.02 $ Date 17. Apr 1999 $ Not compiled $
%
%
% Copyright
% Claus A. Andersson 1995-1999
% Chemometrics Group, Food Technology
% Department of Food and Dairy Science
% Royal Veterinary and Agricultutal University
% Rolighedsvej 30, T254
% DK-1958 Frederiksberg
% Denmark
% E-mail claus@andersson.dk
for i = 1:length(Factors);
DimX(i)=size(Factors{i},1);
end
i = find(DimX==0);
for j = 1:length(i)
DimX(i(j)) = size(G,i(j));
end
if nargin<2, %Must be PARAFAC
Fac=size(Factors{1},2);
G=[];
else
for f = 1:length(Factors)
if isempty(Factors{f})
Fac(f) = -1;
else
Fac(f) = size(Factors{f},2);
end;
end
end
if ~exist('Om')
Om=[];
end;
if isempty(Om)
Om=0;
end;
if size(Fac,2)==1,
Fac=Fac(1)*ones(1,size(DimX,2));
end;
N=size(Fac,2);
if size(DimX,2)>size(Fac,2),
Fac=Fac*ones(1,size(DimX,2));
end;
N=size(Fac,2);
Fac_orig=Fac;
i=find(Fac==-1);
if ~isempty(i)
Fac(i)=zeros(1,length(i));
Fac_ones(i)=ones(1,length(i));
end;
DimG=Fac;
i=find(DimG==0);
DimG(i)=DimX(i);
if isempty(G),
G=neye(DimG);
end;
G = reshape(G,size(G,1),prod(size(G))/size(G,1));
% reshape factors to old format
ff = [];
for f=1:length(Factors)
ff=[ff;Factors{f}(:)];
end
Factors = ff;
if DimG(1)~=size(G,1) | prod(DimG(2:N))~=size(G,2),
help nmodel
fprintf('nmodel.m : ERROR IN INPUT ARGUMENTS.\n');
fprintf(' Dimension mismatch between ''Fac'' and ''G''.\n\n');
fprintf('Check this : The dimensions of ''G'' must correspond to the dimensions of ''Fac''.\n');
fprintf(' If a PARAFAC model is established, use ''[]'' for G.\n\n');
fprintf(' Try to reproduce the error and request help at rb@kvl.dk\n');
return;
end;
if sum(DimX.*Fac) ~= length(Factors),
help nmodel
fprintf('nmodel.m : ERROR IN INPUT ARGUMENTS.\n');
fprintf(' Dimension mismatch between the number of elements in ''Factors'' and ''DimX'' and ''Fac''.\n\n');
fprintf('Check this : The dimensions of ''Factors'' must correspond to the dimensions of ''DimX'' and ''Fac''.\n');
fprintf(' You may be using results from different models, or\n');
fprintf(' You may have changed one or more elements in ''Fac'' or ''DimX'' after ''Factors'' have been calculated.\n\n');
fprintf(' Read the information above for information on arguments.\n');
return;
end;
FIdx0=cumsum([1 DimX(1:N-1).*Fac(1:N-1)]);
FIdx1=cumsum([DimX.*Fac]);
if Om==0,
Orthomode=1;
end;
if Om==1,
Orthomode=0;
end;
if Om==2,
Orthomode=1;
for c=1:N,
if Fac_orig(c)~=-1,
A=reshape(Factors(FIdx0(c):FIdx1(c)),DimX(c),Fac(c));
AA=A'*A;
ssAA=sum(sum(AA.^2));
ssdiagAA=sum(sum(diag(AA).^2));
if abs(ssAA-ssdiagAA) > 100*eps;
Orthomode=0;
end;
end;
end;
end;
if Orthomode==0,
Zmi=prod(abs(Fac_orig(2:N)));
Zmj=prod(DimX(2:N));
Zm=zeros(Zmi,Zmj);
DimXprodc0 = 1;
Facprodc0 = 1;
Zm(1:Facprodc0,1:DimXprodc0)=ones(Facprodc0,DimXprodc0);
for c=2:N,
if Fac_orig(c)~=-1,
A=reshape(Factors(FIdx0(c):FIdx1(c)),DimX(c),Fac(c));
DimXprodc1 = DimXprodc0*DimX(c);
Facprodc1 = Facprodc0*Fac(c);
Zm(1:Facprodc1,1:DimXprodc1)=ckron(A',Zm(1:Facprodc0,1:DimXprodc0));
DimXprodc0 = DimXprodc1;
Facprodc0 = Facprodc1;
end;
end;
if Fac_orig(1)~=-1,
A=reshape(Factors(FIdx0(1):FIdx1(1)),DimX(1),Fac(1));
Xm=A*G*Zm;
else
Xm=G*Zm;
end;
elseif Orthomode==1,
CurDimX=DimG;
Xm=G;
newi=CurDimX(2);
newj=prod(CurDimX)/CurDimX(2);
Xm=reshape(Xm',newi,newj);
for c=2:N,
if Fac_orig(c)~=-1,
A=reshape(Factors(FIdx0(c):FIdx1(c)),DimX(c),Fac(c));
Xm=A*Xm;
CurDimX(c)=DimX(c);
else
CurDimX(c)=DimX(c);
end;
if c~=N,
newi=CurDimX(c+1);
newj=prod(CurDimX)/CurDimX(c+1);
else,
newi=CurDimX(1);
newj=prod(CurDimX)/CurDimX(1);
end;
Xm=reshape(Xm',newi,newj);
end;
if Fac_orig(1)~=-1,
A=reshape(Factors(FIdx0(1):FIdx1(1)),DimX(1),Fac(1));
Xm=A*Xm;
end;
end;
Xm = reshape(Xm,DimX);
function G=neye(Fac);
% NEYE Produces a super-diagonal array
%
%function G=neye(Fac);
%
% $ Version 2.00 $ May 2001 $ Changed to array notation $ RB $ Not compiled $
% $ Version 1.00 $ Date 5. Aug. 1998 $ Not compiled $
%
% This algorithm requires access to:
% 'getindxn'
%
% See also:
% 'parafac' 'maxvar3' 'maxdia3'
%
% ---------------------------------------------------------
% Produces a super-diagonal array
% ---------------------------------------------------------
%
% G=neye(Fac);
%
% Fac : A row-vector describing the number of factors
% in each of the N modes. Fac must be a 1-by-N vector.
% Ex. [3 3 3] or [2 2 2 2]
% 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.
%
% Claus A. Andersson
% Chemometrics Group, Food Technology
% Department of Food and Dairy Science
% Royal Veterinary and Agricultutal University
% Rolighedsvej 30, DK-1958 Frederiksberg, Denmark
% E-mail claus@andersson.dk
N=size(Fac,2);
if N==1,
fprintf('Specify ''Fac'' as e vector to define the order of the core, e.g.,.\n')
fprintf('G=eyecore([2 2 2 2])\n')
end;
G=zeros(Fac(1),prod(Fac(2:N)));
for i=1:Fac(1),
[gi,gj]=getindxn(Fac,ones(1,N)*i);
G(gi,gj)=1;
end;
G = reshape(G,Fac);
function [i,j]=getindxn(R,Idx);
%GETINDXN
%
%[i,j]=GetIndxn(R,Idx)
%
% Copyright
% Claus A. Andersson 1995-
% Chemometrics Group, Food Technology
% Department of Food and Dairy Science
% Royal Veterinary and Agricultutal University
% Rolighedsvej 30, T254
% DK-1958 Frederiksberg
% Denmark
% E-mail: claus@andersson.dk
l=size(Idx,2);
i=Idx(1);
j=Idx(2);
if l==3,
j = j + R(2)*(Idx(3)-1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -