function [positions, error, ev] = mds(d, order) % function [positions, error] = mds(d, order) % Compute the multidimensional scaling that produces the best positions % given the two dimensional (symmetric) distance matrix supplied as an input. % Return the order-dimension position data. % Malcolm Slaney and Michele Covell, "Matlab Multidimensional Scaling Tools," % Interval Technical Report #2000-025, 2000 (also available at % http://web.interval.com/papers/2000-025/). % This routine written by Malcolm Slaney - Interval Research Corporation - % May 1998. (c) Copyright Interval Research, May 1998. % This is experimental software and is being provided to Licensee % 'AS IS.' Although the software has been tested on Macintosh, SGI, % Linux, and Windows machines, Interval makes no warranties relating % to the software's performance on these or any other platforms. % % Disclaimer % THIS SOFTWARE IS BEING PROVIDED TO YOU 'AS IS.' INTERVAL MAKES % NO EXPRESS, IMPLIED OR STATUTORY WARRANTY OF ANY KIND FOR THE % SOFTWARE INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY OF % PERFORMANCE, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. % IN NO EVENT WILL INTERVAL BE LIABLE TO LICENSEE OR ANY THIRD % PARTY FOR ANY DAMAGES, INCLUDING LOST PROFITS OR OTHER INCIDENTAL % OR CONSEQUENTIAL DAMAGES, EVEN IF INTERVAL HAS BEEN ADVISED OF % THE POSSIBLITY THEREOF. % % This software program is owned by Interval Research % Corporation, but may be used, reproduced, modified and % distributed by Licensee. Licensee agrees that any copies of the % software program will contain the same proprietary notices and % warranty disclaimers which appear in this software program. % % If no input distance.... generate a set of test points (x) and then compute % the distances between points. Use this as input data. % By Malcolm, straight from the book. if nargin < 1 x=[1 2 1 2; 1 1 3 4]; n = size(x,2); x(1,:) = x(1,:)-sum(x(1,:))/n; x(2,:) = x(2,:)-sum(x(2,:))/n; d = zeros(n,n); for i=1:n for j=1:n d(i,j) = sqrt(sum((x(:,i)-x(:,j)).^2)); end end end if nargin < 2 order = 2; end n = size(d,1); A = -1/2*d.^2; ardot = 1/n * ones(n,1) * sum(A); asdot = 1/n * sum(A')' * ones(1,n); adotdot = 1/n/n * sum(sum(A)) * ones(n,n); B = A - ardot - asdot + adotdot; [u,s,v] = svd(B); positions = (v*s.^.5)'; if size(positions,1) > 1 plot(positions(1,:),positions(2,:),'bx'); title('2D MDS Solutions'); if nargin < 1 hold on plot(x(1,:),x(2,:),'r+') title('2D MDS Solutions (red are test input locations)'); hold off end drawnow; end ev = diag(s); error = []; if nargout > 1 for order=1:min(10,size(positions,1)) error(order) = 0; for i=1:n for j=1:n this_d = sqrt(sum((positions(1:order,i) - ... positions(1:order,j)).^2)); error(order) = error(order) + ... (this_d - d(i,j)).^2; end end end end positions = positions(1:order,:);