1
\$\begingroup\$

In question "Dictionary based non-local mean implementation in Matlab", the Manhattan distance between two three-dimensional structures can be calculated by ManhattanDistance function. In this post, besides Manhattan distance, the functions for calculating Euclidean distance, squared Euclidean distance and maximum distance are presented here.

In mathematical form, Euclidean distance of two three-dimensional inputs X1 and X2 with size N1 x N2 x N3 is defined as

$$ \begin{split} D_{Euclidean}(X_{1}, X_{2}) & = \left\|X_{1} - X_{2}\right\|_{2} \\ & = \sqrt{\sum_{k_{1} = 1}^{N_{1}} \sum_{k_{2} = 1}^{N_{2}} \sum_{k_{3} = 1}^{N_{3}} {( X_{1}(k_{1}, k_{2}, k_{3}) - X_{2}(k_{1}, k_{2}, k_{3}) )}^{2}} \end{split} $$

Squared Euclidean distance of two three-dimensional inputs X1 and X2 with size N1 x N2 x N3 is defined as

$$ \begin{split} D_{Euclidean}^{2}(X_{1}, X_{2}) & = \left\|X_{1} - X_{2}\right\|_{2}^{2} \\ & = \sum_{k_{1} = 1}^{N_{1}} \sum_{k_{2} = 1}^{N_{2}} \sum_{k_{3} = 1}^{N_{3}} {( X_{1}(k_{1}, k_{2}, k_{3}) - X_{2}(k_{1}, k_{2}, k_{3}) )}^{2} \end{split} $$

Maximum distance of two three-dimensional inputs X1 and X2 with size N1 x N2 x N3 is defined as

$$ \begin{split} D_{Maximum}(X_{1}, X_{2}) & = \left\|X_{1} - X_{2}\right\|_{\infty} \\ & = \max_{k_{1}, k_{2}, k_{3}} {( X_{1}(k_{1}, k_{2}, k_{3}) - X_{2}(k_{1}, k_{2}, k_{3}) )} \end{split} $$

The experimental implementation

  • EuclideanDistance function: for calculating Euclidean distance between two inputs

    function [output] = EuclideanDistance(X1, X2)
    %EUCLIDEANDISTANCE Calculate Euclidean distance between two inputs
        if size(X1)~=size(X2)
            fprintf("Sizes of inputs are not equal!\n");
            return;
        end
        output = sqrt(SquaredEuclideanDistance(X1, X2));
    end
    
  • SquaredEuclideanDistance function: for calculating squared Euclidean distance between two inputs

    function [output] = SquaredEuclideanDistance(X1, X2)
    %SQUAREDEUCLIDEANDISTANCE Calculate squared Euclidean distance between two inputs
        if size(X1)~=size(X2)
            fprintf("Sizes of inputs are not equal!\n");
            return;
        end
        output = sum((X1 - X2).^2, 'all');
    end
    
  • MaximumDistance function: for calculating maximum distance between two inputs

    function [output] = MaximumDistance(X1, X2)
    %MAXIMUMDISTANCE Calculate maximum distance between two inputs
        if size(X1)~=size(X2)
            fprintf("Sizes of inputs are not equal!\n");
            return;
        end
        output = max(X1 - X2, [], 'all');
    end
    

Test case

%%  Three-dimensional test case
fprintf("Three-dimensional test case\n");
SizeNum = 8;
A = ones(SizeNum, SizeNum, SizeNum) .* 0.2;
B = ones(SizeNum, SizeNum, SizeNum) .* 0.1;

ED = EuclideanDistance(A, B)
MD = MaximumDistance(A, B)
SED = SquaredEuclideanDistance(A, B)

%%  Four-dimensional test case
fprintf("Four-dimensional test case\n");
SizeNum = 8;
A = ones(SizeNum, SizeNum, SizeNum, SizeNum) .* 0.2;
B = ones(SizeNum, SizeNum, SizeNum, SizeNum) .* 0.1;

ED = EuclideanDistance(A, B)
MD = MaximumDistance(A, B)
SED = SquaredEuclideanDistance(A, B)

%%  Five-dimensional test case
fprintf("Five-dimensional test case\n");
SizeNum = 8;
A = ones(SizeNum, SizeNum, SizeNum, SizeNum, SizeNum) .* 0.2;
B = ones(SizeNum, SizeNum, SizeNum, SizeNum, SizeNum) .* 0.1;

ED = EuclideanDistance(A, B)
MD = MaximumDistance(A, B)
SED = SquaredEuclideanDistance(A, B)

%%  Six-dimensional test case
fprintf("Six-dimensional test case\n");
SizeNum = 8;
A = ones(SizeNum, SizeNum, SizeNum, SizeNum, SizeNum, SizeNum) .* 0.2;
B = ones(SizeNum, SizeNum, SizeNum, SizeNum, SizeNum, SizeNum) .* 0.1;

ED = EuclideanDistance(A, B)
MD = MaximumDistance(A, B)
SED = SquaredEuclideanDistance(A, B)

The output result of testing code above:

Three-dimensional test case

ED =

    2.2627


MD =

    0.1000


SED =

    5.1200

Four-dimensional test case

ED =

    6.4000


MD =

    0.1000


SED =

   40.9600

Five-dimensional test case

ED =

   18.1019


MD =

    0.1000


SED =

  327.6800

Six-dimensional test case

ED =

   51.2000


MD =

    0.1000


SED =

   2.6214e+03

All suggestions are welcome.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Your test cases don’t test the error condition handling:

if size(X1)~=size(X2)
    fprintf("Sizes of inputs are not equal!\n");
    return;
end

In the case of two inputs with different dimensionality, you will see an error message saying you’re comparing vectors of different length. This is because size will return, say a 1x2 matrix and a 1x3 matrix, and you cannot compare those with ~=, that operator requires equal-size arrays.

In case of two inputs with the same number of dimensions but different sizes, you will see your message printed to screen, and then an error that the output argument was not assigned a value. This is because you return without assigning to output.

If there is an error condition, you should use error to flag it. You can’t produce an output value and have calling code continue to process normally. Throw an error and either have the calling code handle it or the program stop altogether.

The proper way to test for equal input sizes is as follows:

if ~isequal(size(X1), size(X2))
   error('Sizes of inputs are not equal!')
end

isequal will return false if the two arrays are of different size or do not have equal values.

You could also use assert, or the new input parameter specification system.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.