1
\$\begingroup\$

This is a follow-up question for Calculate distances between two multi-dimensional arrays in Matlab and Mean and variance of element-wise distances in a set of multi-dimensional arrays in Matlab. For avoiding calculating distances and average twice, I am trying to propose a different implementation which is to calculate all distances first and then calculate mean and variance.

The experimental implementation

  • MeanVarIntraEuclideanDistances function

    function [Mean, Variance] = MeanVarIntraEuclideanDistances(X1)
        Distances = IntraEuclideanDistances(X1);
        k = 2;
        NormalizationFactor = (1 / nchoosek(size(X1, 4), k));
        Mean = sum(Distances, 'all') * NormalizationFactor;
        Variance = sum((Distances - Mean).^2, 'all') * NormalizationFactor;
    end
    
  • IntraEuclideanDistances function: returns the element-wise distances in an array

    function Distances = IntraEuclideanDistances(X1)
        N = size(X1, 4);
        Distances = zeros(1, N * (N - 1) / 2);
        for i = 1:N
            element1 = X1(:, :, :, i);
            for j = i:N
                element2 = X1(:, :, :, j);
                DistIndex = (N + (N - (i - 1) + 1)) * (i - 1) / 2 + (j - i + 1);
                Distances(DistIndex) = EuclideanDistance(element1, element2);
            end
        end
    end
    
  • EuclideanDistance function

    function [output] = EuclideanDistance(X1, X2)
    %EUCLIDEANDISTANCE Calculate Euclidean distance between two inputs
        if ~isequal(size(X1), size(X2))
          error('Sizes of inputs are not equal!')
        end
        output = sqrt(SquaredEuclideanDistance(X1, X2));
    end
    
  • SquaredEuclideanDistance function

    function [output] = SquaredEuclideanDistance(X1, X2)
    %SQUAREDEUCLIDEANDISTANCE Calculate squared Euclidean distance between two inputs
        if ~isequal(size(X1), size(X2))
            error('Sizes of inputs are not equal!')
        end
        output = sum((X1 - X2).^2, 'all');
    end
    

Test case

%%  Preparing data

DataCount = 10;
sizex = 8;
sizey = 8;
sizez = 8;
Collection = ones(sizex, sizey, sizez, DataCount);
for i = 1:DataCount
    Collection(:, :, :, i) = ones(sizex, sizey, sizez) .* i;
end

%%  Function testing

[Mean, Variance] = MeanVarIntraEuclideanDistances(Collection)

The output of test case:

Mean =

   82.9672


Variance =

   4.0328e+03

All suggestions are welcome.

The summary information:

\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.