I wonder if it's possible to improve rotation in Procrustes Analysis? For example, If I give you this example. Assume that we have data like this:
% Data
X = [linspace(0, 10)', linspace(10, 10)'; linspace(10, 10)' linspace(10, 0)'];
Y = 3*[linspace(0, -10)', linspace(-10, -10)'; linspace(-10, -10)' linspace(-10, 0)'];
And we want to
- Scale
- Translate
- Rotate
If I'm using the Procrustes analysis code from this question Procrustes Analysis with NumPy?
function [X0, Y0, Z, d] = procrustes(X, Y)
% Procrustes analysis in MATLAB
% Check if scaling and reflection are specified, otherwise use defaults
if nargin < 3
scaling = true;
end
if nargin < 4
reflection = 'best';
end
[n, m] = size(X);
[ny, my] = size(Y);
muX = mean(X);
muY = mean(Y);
X0 = X - muX;
Y0 = Y - muY;
ssX = sum(X0.^2);
ssY = sum(Y0.^2);
% Centred Frobenius norm
normX = sqrt(sum(ssX));
normY = sqrt(sum(ssY));
% Scale to equal (unit) norm
X0 = X0 / normX;
Y0 = Y0 / normY;
if my < m
Y0 = [Y0, zeros(n, m-my)];
end
% Optimum rotation matrix of Y
A = X0.' * Y0;
[U, S, Vt] = svd(A, 'econ');
V = Vt.';
T = V * U';
if ~strcmp(reflection, 'best')
% Does the current solution use a reflection?
have_reflection = det(T) < 0;
% If that's not what was specified, force another reflection
if ~strcmp(reflection, have_reflection)
V(:,end) = -V(:,end);
S(end,end) = -S(end,end);
T = V * U';
end
end
traceTA = sum(diag(S));
if scaling
% Optimum scaling of Y
b = traceTA * normX / normY;
% Standardized distance between X and b*Y*T + c
d = 1 - traceTA^2;
% Transformed coordinates
Z = normX * traceTA * Y0 * T + muX;
else
b = 1;
d = 1 + sum(ssY) / sum(ssX) - 2 * traceTA * normY / normX;
Z = normY * Y0 * T + muX;
end
% Transformation matrix
if my < m
T = T(1:my, :);
end
c = muX - b * muY * T;
% Transformation values
tform = struct('rotation', T, 'scale', b, 'translation', c);
end
I get this result
% Procrustes analysis
[X, Y, Z, d] = procrustes(X, Y);
% Plot
plot(X(:,1), X(:,2),'r-', Y(:,1), Y(:,2),'b-');
legend('X = Target','Y = Comparison')
Question:
In this situation, scaling and translation are only made, not rotation. Why is rotation not made here? Can that be situations when Procrustes won't do rotation?