function result = mlr(x,y,varargin) %MLR is the classical least squares estimator for multivariate multiple % linear regression. It can handle both one or several ('multiple') % predictor variables and one or several ('multivariate') response variables. % If the regression model contains an intercept, the x-matrix may not contain % a column with ones. % If there is only one response variable, the function ols.m is called. % % See for example: % R.A. Johnson and D.W. Wichern, % "Applied multivariate statistical analysis (Fifth Edition)", % Prentice Hall, chapter 7. % % Required input arguments: % x : Data matrix of the explanatory variables % (n observations in rows, p variables in columns) % y : Data matrix of the response variables % (n observations in rows, q variables in columns) % % Optional input arguments: % intercept : logical flag: if 1, a model with constant term will be % fitted; if 0, no constant term will be included. (default: 1) % plots : If equal to one, a menu is shown which allows to draw several plots, % such as residual plots and a regression outlier map. (default) % If 'plots' is equal to zero, all plots are suppressed. % See also makeplot.m % % I/O: result=mlr(x,y,'plots',0); % The user should only give the input arguments that have to change their default value. % % The output is a structure containing: % % result.slope : Slope estimate % result.int : Intercept estimate % result.fitted : Fitted values % result.res : Residuals % result.stdres : Standardized residuals % result.cov : Estimated variance-covariance matrix of the residuals % result.rsquared : R-squared value % result.md : Score distances (Mahalanobis distances in x-space) % result.resd : Residual distances (when there are several response variables). % If univariate regression is performed, it contains the standardized residuals. % result.cutoff : Cutoff values for the score and residual distances % result.flag : The observations whose residual distance is larger than result.cutoff.resd % receive a flag equal to zero. The other observations receive a flag 1. % result.class : 'MLR' (when q > 1) or 'LS' (when q = 1) % % This function is part of LIBRA: the Matlab Library for Robust Analysis, % available at: % http://wis.kuleuven.be/stat/robust.html % % Written by Nele Smets on 13/12/2003 % Last update: 05/04/2004 % q=size(y,2); p=size(x,2); geg=[x,y]; [n,m]=size(geg); intercept=ones(n,1); default=struct('plots',1,'intercept',1); list=fieldnames(default); options=default; IN=length(list); i=1; counter=1; if nargin>2 % % placing inputfields in array of strings % for j=1:nargin-2 if rem(j,2)~=0 chklist{i}=varargin{j}; i=i+1; end end % Checking which default parameters have to be changed % and keep them in the structure 'options'. while counter<=IN index=strmatch(list(counter,:),chklist,'exact'); if ~isempty(index) % in case of similarity for j=1:nargin-2 % searching the index of the accompanying field if rem(j,2)~=0 % fieldnames are placed on odd index if strcmp(chklist{index},varargin{j}) I=j; end end end options=setfield(options,chklist{index},varargin{I+1}); index=[]; end counter=counter+1; end end %%%%%%%%%Main part%%%%%%% if q==1 result=libra_ols(x,y,'intercept', options.intercept,'plots',options.plots); else cmean=mean(geg); ccovar=cov(geg); meanx=cmean(1:p)'; meany=cmean((p+1):m)'; cy=mcenter(y); covarx=ccovar(1:p,1:p); covary=ccovar((p+1):m,(p+1):m); covarxy=ccovar(1:p,(p+1):m); covaryx=covarxy'; res.betas=[inv(covarx)*covarxy; (meany-(covaryx*inv(covarx)*meanx))']; res.fitted=[x intercept]*res.betas; res.residuals=y-res.fitted; res.cov=covary-res.betas(1:p,1:q)'*covarx*res.betas(1:p,1:q); res.stdresid= res.residuals./repmat(diag(res.cov)',n,1); res.rsquared= 1-(det(res.residuals'*res.residuals)/det(cy'*cy)); res.class='MLR'; % x-distances (md) needed in diagnostic regression plot if (-log(det(ccovar))/m) > 50 res.md='singularity'; res.resd='singularity'; else res.md=sqrt(libra_mahalanobis(x,cmean(1:p),'cov',covarx))'; cen=zeros(q,1)'; res.resd=sqrt(libra_mahalanobis(res.residuals,cen,'cov',res.cov))'; end %cutoff values res.cutoff.md=sqrt(chi2inv(0.975,p)); res.cutoff.resd=sqrt(chi2inv(0.975,q)); res.flag=(abs(res.resd)<=res.cutoff.resd); result=struct('slope',{res.betas(1:p,:)},'int',{res.betas(p+1,:)}, ... 'fitted',{res.fitted},'res',{res.residuals},'stdres',{res.stdresid},... 'cov',{res.cov},'rsquared',{res.rsquared},'md',{res.md},'resd',{res.resd},... 'cutoff',{res.cutoff},'flag',{res.flag},'class',{res.class}); if ~intercept result=setfield(result, 'int', 0) end try if options.plots==1 makeplot(result) end catch %output must be given even if plots are interrupted %> delete(gcf) to get rid of the menu end end