source: distools/dprocrustdm.m @ 137

Last change on this file since 137 was 79, checked in by bduin, 11 years ago
File size: 5.8 KB
RevLine 
[10]1% DPROCRUSTDM Distance Matrix between Datasets based on Extended Procrustes Problem
2%
3%   [D,T] = DPROCRUSTDM(X,Y,SC,EXT)
4%
5% INPUT
6%   X   N x Mx or N x Mx x Kx data
7%   Y   N x My or N x My x Ky data; My <= Mx
8%   SC  Parameter (1/0) indicating whether to scale the distance to [0,1]
9%       by normalizing X and Y by their Frobenius norms (optional; default: 1)
10%   EXT Parameter (1/0) indicating extended (1) or orthogonal (0)
11%       Procrustes problem (optional; default: 1)
12%
13% OUTPUT
14%   D   Kx x Ky Distance matrix
15%   T   Kx x Ky Transformation structure
16%
17% DEFAULT
18%   SC  = 1
19%   EXT = 1
20%
21% DESCRIPTION
22% Given two 2D matrices X and Y, extended Procrustes analysis, EXT = 1, finds
23% a linear transformation based on shift, orthogonal transformation and scaling
24% of the points in Y to fit the points in X.  This is done by minimizing the sum
25% of squared differences, which is also the Frobenius norm between X and the
26% transformed Yt. Yt = alpha*Y*Q+1*beta^T, where alpha is the scaling scalar,
27% Q is the orthogonal transformation, beta is the shift vector and 1 is the
28% vector of all ones. If SC = 0, then the resulting difference is returned as
29% the dissimilarity D. So, the parameters are found in the least square sense
30% such that  min ||X - alpha*Y*Q - 1*beta^T||^2 holds.
31% Then, D = norm(X-Yt,'Frobenius').
32% If SC = 1, then the resulting distance D is scaled to [0,1] by normalizing it
33% by NORM(Xc,'Frobenius'), where Xc is X shifted to the origin.
34%
35% Orthogonal Procrustes analysis, EXT = 0, neglects alpha and beta and focuses
36% on the orthogonal transformation only. So, the above holds for Yt = Y*Q.
37%
38% X and Y should have the same number of points, as Procrustes analysis matches
39% X(i,:) to Y(i,:). If dim(Y) < dim(X), then columns of zeros are added to Y.
40% If X and Y are 3D matrices, then we consider sets of 2D matrices to be
41% compared, which results in a Kx x Ky distance matrix D.
42%
43% IMPORTANT
44% Note that D = DPROCRUST(X,X,0,1) is assymetric and D = DPROCRUST(X,X,S,EXT)
45% is symmetric, otherwise.
46%
47% T is a structure of the size Kx x Ky with the fields of alpha, beta and Q
48% if EXT = 1 and with the field of Q, if EXT = 0. For instance, T(i,j).Q is the
49% orthogonal trnasformation of Y(:,:,j) to fit Y(:,:,i).
50%
51% This routine can be used to match two results of MDS, or KPCA/PSEM for
52% an Euclidean embedding, or two shapes (described by contour points) of
53% known point correspondences.
54%
55% SEE ALSO
[79]56% MDS, PCAM, PSEM, KPCA, MAPPINGS, DATASETS
[10]57%
58% REFERENCE
59% 1. J.C. Gower, Generalized Procrustes analysis. Psychometrika, 40, 33-51, 1975.
60% 2. I. Borg, and P. Groenen, Modern Multidimensional Scaling. Springer, New York, 1997.
61% 3. http://e-collection.ethbib.ethz.ch/ecol-pool/bericht/bericht_363.pdf
62
63% Copyright: Elzbieta Pekalska, ela.pekalska@googlemail.com
64% Faculty EWI, Delft University of Technology and
65% School of Computer Science, University of Manchester
66
67
68
69function [D,T] = dprocrustdm(X,Y,normalize,extPA)
70
71% Let X and Y be first centered at the origin.
72% [U,S,V]=preig(X'*Y);
73%
74% For non-normalized data, the transformation is given as
75% Q     = V*U';
76% alpha = trace(X'*Y*Q) / trace(Y'*Y) = sum(diag(S)) / norm(Y,'Frobenius')^2
77% beta  = (mean(X) - alpha*mean(Y)*Q);
78
79if nargin < 3,
80  normalize = 1;
81end
82if nargin < 4,
83  extPA = 1;
84end
85
86if normalize~=0 & normalize ~=1,
87  error('SC should be either 0 or 1.');
88end
89
90if extPA~=0 & extPA~=1,
91  error('EXT should be either 0 or 1.');
92end
93
94if isdataset(X), X = +X; end
95if isdataset(Y), Y = +Y; end
96
97[nx,mx,kx] = size(X);
98[ny,my,ky] = size(Y);
99
100if ny ~= nx,
101  error('X and Y should have the same number of points.');
102end
103if my > mx,
104  error('Y cannot have more columns (dimensions) than X.');
105end
106% Add columns of zero if dim(Y) < dim(X)
107if my < mx,
108  if ky == 1,
109    Y = [Y zeros(ny,mx-my)];
110  else
111    Y(:,my+1:mx,:) = zeros(ny,mx-my,ky);
112  end
113end
114
115XX = X;
116YY = Y;
117
118% Center the data at the origin
119Xme = mean(X,1);
120Yme = mean(Y,1);
121X   = X - repmat(Xme,nx,1);
122Y   = Y - repmat(Yme,ny,1);
123
124if normalize,
125  % Compute the square Frobenius norm and scale the data
126  % For data A, norm(A,'Frob') = sqrt(trace(A'*A)) = sqrt(sum(sum(A.^2))
127  Xfn = sqrt(sum(sum(X.^2,1),2));
128  Yfn = sqrt(sum(sum(Y.^2,1),2));
129  X   = X./repmat(Xfn,nx,mx);
130  Y   = Y./repmat(Yfn,ny,my);
131  Xfn = squeeze(Xfn);
132  Yfn = squeeze(Yfn);
133else
134  Yfn2 = squeeze(sum(sum(Y.^2,1),2));
135end
136
137
138% Find the optimal transformation parameters of Yt = alpha*YY*Q+1*beta^T,
139% rotation matrix Q, scaling alpha and shift vector beta
140if normalize,
141  for i=1:kx
142    for j=1:ky
143      G  = X(:,:,i)'*Y(:,:,j);
144      [U,S,V] = svd(G);
145      Q  = V*U';
146      scY(i,j) = sum(diag(S));
147      if nargout > 1,
148        T(i,j).Q = Q;
149        if extPA,
150          T(i,j).alpha = scY(i,j) * (Xfn(i) /Yfn(j));
151          T(i,j).beta  = squeeze(Xme(:,:,i)) - T(i,j).alpha*squeeze(Yme(:,:,j)) * T(i,j).Q;
152        end
153      end
154    end
155  end
156  % Distance between X and Yt = alpha*Y*Q+1*beta^T
157  D = real(sqrt(1 - scY.^2));
158else
159  for i=1:kx
160    for j=1:ky
161      G = X(:,:,i)'*Y(:,:,j);
162      [U,S,V] = svd(G);
163      Q = V*U';
164      scY(i,j) = sum(diag(S));
165      if nargout > 1,
166        T(i,j).Q = Q;
167        if extPA,
168          T(i,j).alpha = scY(i,j) ./ Yfn2(j);
169          T(i,j).beta  = squeeze(Xme(:,:,i)) - T(i,j).alpha*squeeze(Yme(:,:,j)) * T(i,j).Q;
170          D(i,j) = norm(XX(:,:,i) -T(i,j).alpha*YY(:,:,j)*T(i,j).Q+ones(ny,1)*T(i,j).beta,'fro');
171        else
172          D(i,j) = norm(XX(:,:,i) -YY(:,:,j)*T(i,j).Q,'fro');
173        end
174      else
175        if extPA,
176          alpha  = scY(i,j) ./ Yfn2(j);
177          beta   = squeeze(Xme(:,:,i)) - alpha*squeeze(Yme(:,:,j)) * Q;
178          D(i,j) = norm(XX(:,:,i) - alpha*YY(:,:,j)*Q + ones(ny,1)*beta,'fro');
179        else
180          D(i,j) = norm(XX(:,:,i) - YY(:,:,j)*Q,'fro');
181        end
182      end
183    end
184  end
185end
186
187% Take care that distances are real and nonnegative
188D = real(D);
189D(find (D < 0)) = 0;
190if kx == ky & kx > 1 & isymm(D,1e-12),
191  D(1:kx+1:end) = 0;
192  D = 0.5*(D+D');
193end
Note: See TracBrowser for help on using the repository browser.