How to improve rotation in Procrustes Analysis

40 views Asked by At

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)'];

enter image description here

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')

enter image description here

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?

0

There are 0 answers